从庞大的Excel电子表格中获取计算值的最佳方法

时间:2019-06-18 12:01:03

标签: php .net excel epplus phpspreadsheet

好的,所以我有一个包含15页完整公式的Excel电子表格。我没有保密协议,无法向您显示电子表格。我需要以编程方式输入Web用户提交的值,计算输出并将结果返回给用户。

将电子表格的计算转换为纯代码对于项目预算来说将花费太长时间。

我尝试使用 PhpSpreadsheet :-

$workbook = \PhpOffice\PhpSpreadsheet\IOFactory::load("modeller.xlsx");

$sheet = $workbook->getSheet(1);

$c13 = $sheet->getCell('C13')->getValue();
$c43 = $sheet->getCell('C43')->getValue();

print_r(['C13 Before calc' => $c13, 'C43 Before calc' => $c43]);

$c13 = $sheet->getCell('C13')->setValue(12000);
$c43 = $sheet->getCell('C43')->getCalculatedValue();

print_r(['C13 After calc' => $c13, 'C43 After calc' => $c43]);

但是它不能处理复杂性-尝试并运行计算需要花费很多时间,然后才陷入Fatal error: Maximum function nesting level of '256' reached, aborting!

我还尝试学习一些.NET,并使用了 EPPlus :-

var fi = new FileInfo(@"C:\dotnet\webapps\test\modeller.xlsx");

using (var p = new ExcelPackage(fi))
{
    var ws = p.Workbook.Worksheets["Inputs & Outputs"];

    Console.WriteLine("\tBefore calc Cell(C13).Value={0}",  ws.Cells["C13"].Value);
    Console.WriteLine("\tBefore calc Cell(C43).Value={0}",  ws.Cells["C43"].Value);

    ws.Cells["C13"].Value = 12000;

    ws.Calculate();

    Console.WriteLine("\tAfter calc Cell(C13).Value={0}",  ws.Cells["C13"].Value);
    Console.WriteLine("\tAfter calc Cell(C43).Value={0}",  ws.Cells["C43"].Value);
}

尽管运行速度比PhpSpreadsheet快,但它仍然太慢并且始终无法计算输出-该值始终为#VALUE!

我最后的选择是使用 COM 直接与Excel副本进行交互并运行计算:-

$xl = new COM("Excel.Application");

$xl->Visible = false;
$xl->DisplayAlerts = false;

$file = 'C:\\wamp\\www\\test\\modeller.xlsx';

$wb = $xl->Workbooks->Open($file);

$ws = $wb->Worksheets('Inputs & Outputs');

$c13 = $ws->Range('C12')->Value;
$c43 = $ws->Range('C43')->Value;

print_r(['C13 Before calc' => $c13, 'C43 Before calc' => $c43]);

$ws->Range('C12')->Value = 12000;

$ws->Calculate();

$c13 = $ws->Range('C12')->Value;
$c43 = $ws->Range('C43')->Value;

print_r(['C13 After calc' => $c13, 'C43 After calc' => $c43]);

$wb->Close();

这可以工作(经过多年对Component Services的了解),并且在我的开发机器上仅花费约2秒的时间。但是我是worried about the scalability of this approach-可能有数百个并发请求都打开一个Excel实例。

我真的不想使用COM。还有我没有考虑过的另一种方法吗?

0 个答案:

没有答案
相关问题