У меня проблема с phpExcel. Мне было поручено создать отчет, который содержит довольно сложную формулу. Формула включает в себя несколько строк, но phpExcel, похоже, не так. Полученный файл показывает часть формулы, вырезав ее в одной из точек конкатенации. Я удалил знак =, чтобы увидеть, что такое phpExcel, когда формула представлена в виде обычной строки, и она отлично работает. Я могу вручную поставить знак = обратно, и формула работает как ожидалось.
Я собрал тестовый файл, чтобы продемонстрировать, что происходит. Я приложил изображение, показывающее, что выводит этот скрипт. Как мы видим, формулы в столбцах W и X были обрезаны на одной из конкатенаций.
require_once('/PHPExcel1.8.0/PHPExcel.php');
$Excel = new PHPExcel();
// Set file properties
$Excel->getProperties()->setCreator('Spreadsheet Author');
$worksheet = $Excel->getActiveSheet();
// Change the name of the first worksheet
$worksheet->setTitle('Report');
$Excel->createSheet(1);
// Set the header rows
$worksheet
->setCellValue('A1', 'Report Title')
->setCellValue('A3', 'Header 1')->setCellValue('B3', 'Header 2')->setCellValue('C3', 'Header 3')->setCellValue('D3', 'Header 4')
->setCellValue('E3', 'Header 5')->setCellValue('F3', 'Header 6')->setCellValue('G3', 'Header 7')->setCellValue('H3', 'Header 8')
->setCellValue('I3', 'Header 9')->setCellValue('J3', 'Header 10')->setCellValue('K3', 'Header 11')->setCellValue('L3', 'Header 12')
->setCellValue('M3', 'Header 13')->setCellValue('N3', 'Header 14')->setCellValue('O3', 'Header 15')->setCellValue('P3', 'Header 16')
->setCellValue('Q3', 'Header 17')->setCellValue('R3', 'Header 18')->setCellValue('S3', 'Header 19')->setCellValue('T3', 'Header 20')
->setCellValue('U3', 'Header 21')
->setCellValue('V3', 'Header 22')
->setCellValue('W3', 'Formula 2 (95% CI)')
->setCellValue('X3', 'Formula 2 (95% CI)');
// Switch pages
$Excel->setActiveSheetIndex(1);
$worksheet = $Excel->getActiveSheet();
$worksheet->setTitle('f'); // Make a separate sheet called "f"
$worksheet
->setCellValue('A1', 'n')->setCellValue('B1', 'p')->setCellValue('C1', 'e')
->setCellValue('D1', 'n')->setCellValue('E1', 'p')->setCellValue('F1', 'e');
// Switch back
$Excel->setActiveSheetIndex(0);
$worksheet = $Excel->getActiveSheet();/*
* Populate the data in the spreadsheet
***************************************/
$data = array(
array('String', 'Name', 1427312154, 2, 7, 0, 2, 1, 0, 0, 0, 2, 1, 0),
array('String', 'Name', 1427312154, 25, 148, 0, 85, 0, 0, 0, 53, 99, 15, 0)
);
if (count($data) == 0)
{
echo 'No rows to report';
exit;
}
else
{
// Conversion arrays
$row = 4;
for ($i = 0; $i < count($data); $i++)
{
$worksheet
->setCellValue('A' . $row, $data[$i][0])->setCellValue('B' . $row, $data[$i][1])->setCellValue('C' . $row, date('m/j/Y', $data[2]))
->setCellValue('D' . $row, $data[$i][3])->setCellValue('E' . $row, $data[$i][4])->setCellValue('F' . $row, $data[$i][5])
->setCellValue('G' . $row, $data[$i][6])->setCellValue('H' . $row, $data[$i][7])->setCellValue('I' . $row, $data[$i][8])
->setCellValue('J' . $row, $data[$i][9])->setCellValue('K' . $row, $data[$i][10])->setCellValue('L' . $row, '=SUM(H' . $row . ':K' . $row . ')')
->setCellValue('M' . $row, $data[$i][11])->setCellValue('N' . $row, $data[$i][12])->setCellValue('O' . $row, $data[$i][13])
->setCellValue('P' . $row, '=SUM(L' . $row . ':O' . $row . ')')
->setCellValue('Q' . $row, '=ROUND(F' . $row . '/E' . $row . ',1)')
->setCellValue('R' . $row, '=ROUND(G' . $row . '/E' . $row . ',1)')
->setCellValue('S' . $row, '=ROUND(P' . $row . '/E' . $row . ',1)')
->setCellValue('T' . $row, '=ROUND(L' . $row . '/E' . $row . ',1)')
->setCellValue('U' . $row, '=ROUND(I' . $row . '/E' . $row . ',2)')
->setCellValue('V' . $row, '=ROUND(J' . $row . '/E' . $row . ',3)')
// THIS IS THE TROUBLE SPOT!!!
->setCellValue('W' . $row, '="1:"&ROUND(M' . $row . '/L' . $row . ',1)&", (1:"&ROUND((M' . $row . '/L' . $row . ')-f!B' . $row . ',1)&" to 1: "&ROUND((M' . $row . '/L' . $row . ')+f!B' . $row . ',1)&")"')
// THIS ONE TOO[![enter image description here][1]][1]!!!
->setCellValue('X' . $row, '=ROUND(N' . $row . '/M' . $row . '*100,1)&"%"&" ("&ROUND(((f!E' . $row . '-f!F' . $row . ')*f!D' . $row . ')/(f!D' . $row . '-((f!E' . $row . '-f!F' . $row . ')*f!D' . $row . '))*100,1)&"%"&" to "&ROUND(((f!E' . $row . '+f!F' . $row . ')*f!D' . $row . ')/(f!D' . $row . '-((f!E' . $row . '+f!F' . $row . ')*f!D' . $row . '))*100,1)&"%)"');
// Switch pages
$Excel->setActiveSheetIndex(1);
$worksheet = $Excel->getActiveSheet();
$worksheet
->setCellValue('A' . $row, '=Report!G' . $row . '+Report!H' . $row)
->setCellValue('B' . $row, '=Report!G' . $row . '/A' . $row)
->setCellValue('C' . $row, '=1.96*SQRT(((B' . $row . '*(1-B' . $row . '))/A' . $row . '))')
->setCellValue('D' . $row, '=Report!G' . $row . '+Report!H' . $row)
->setCellValue('E' . $row, '=Report!I' . $row . '/B' . $row)
->setCellValue('F' . $row, '=1.96*SQRT((B' . $row . '*(1-B' . $row . '))/B' . $row . ')');
// Switch pages
$Excel->setActiveSheetIndex(0);
$worksheet = $Excel->getActiveSheet();
$row++;
}
}
// Put the active cell on A1
$worksheet->setSelectedCell('A1');/*
* Close and output file
************************/
// Force download
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="report.xls"');
header('Cache-Control: max-age=0');
// Select the rendering engine and save XLS file
$saveExcel = PHPExcel_IOFactory::createWriter($Excel, 'Excel5');
$saveExcel->setPreCalculateFormulas(false);
$saveExcel->save('php://output');
ОБНОВИТЬ
Я поменял краткую конкатенацию для функции CONCATENATE, чтобы увидеть, получу ли я лучшие результаты.
->setCellValue('W' . $row, '=CONCATENATE("1:",ROUND(M' . $row . '/L' . $row . ',1),", [1:",ROUND((M' . $row . '/L' . $row . ')-f!B' . $row . ',1)," to 1: ",ROUND((M' . $row . '/L' . $row . ')+f!B' . $row . ',1),"]")')
->setCellValue('X' . $row, '=CONCATENATE(ROUND(N' . $row . '/M' . $row . '*100,1),"%"," [",ROUND(((f!E' . $row . '-f!F' . $row . ')*f!D' . $row . ')/(f!D' . $row . '-((f!E' . $row . '-f!F' . $row . ')*f!D' . $row . '))*100,1),"% to ",ROUND(((f!E' . $row . '+f!F' . $row . ')*f!D' . $row . ')/(f!D' . $row . '-((f!E' . $row . '+f!F' . $row . ')*f!D' . $row . '))*100,1),"%]")');
Это породило совершенно другую проблему. В аномальных клетках ничего не было. Нет формулы или вывода любого вида. Поэтому я начал вырезать аргументы из конкатата, чтобы выяснить, не является ли какой-либо из них причиной проблемы. Это оказался самый последний аргумент — буквальный «)» характер. Если я убрал этот кусок конкатата или переключил этот символ на что-то еще, все работало отлично. По какой-то причине phpExcel ненавидит его, когда последний фрагмент concat содержит знак «)». Вместо того, чтобы продолжать эту нелепую проблему, я заменил их скобками на скобки. Если я смогу найти решение этой проблемы, я верну электронную таблицу такой, какой она была.
Задача ещё не решена.
Других решений пока нет …