odan/excel

内存中的Excel文件写入器

0.1.0 2023-11-11 09:43 UTC

This package is auto-updated.

Last update: 2024-09-11 11:30:23 UTC


README

Latest Version on Packagist Software License Build Status Code Coverage Scrutinizer Code Quality Total Downloads

极快的内存中Excel(XLSX)文件写入器。

要求

  • PHP 8.1+

特性

  • 针对最小内存使用和高性能优化。
  • 兼容Microsoft Excel 2007-365(ISO/IEC 29500-1:2016)。
  • 兼容LibreOffice / OpenOffice Calc。
  • 默认采用内存操作。
  • 当内存限制达到时,可选硬盘访问。
  • 工作簿中的多个工作表。
  • 粗体字体的标题列。
  • 自定义工作表名称。
  • 行数据类型:字符串、整数、浮点数
  • 列数据类型:字符串

限制

该包的目的是提供一个非常快且内存高效的Excel(XLSX)文件生成器。它旨在快速输出数据,但不是为了复杂的表格样式。如果您需要更多布局和颜色选项,您可能最好使用不同的包,例如PhpSpreadsheet。

  • 工作簿和工作表数量:受可用内存和系统资源的限制。
  • 最大列数:16,384(规范限制)
  • 最大行数:1,048,576(规范限制)
  • 字体样式:2(行的普通和列的粗体)

安装

composer require odan/excel

使用

use Odan\Excel\ExcelWorkbook;
use Odan\Excel\ZipDeflateStream;

$workbook = new ExcelWorkbook();
$sheet = $workbook->addSheet('My Sheet');

// Write header columns
$columns = ['Date', 'Name', 'Amount'];
$sheet->addColumns($columns);

// Write data
$rows = [
    ['2023-01-31', 'James', 220],
    ['2023-03-28', 'Mike', 153.5],
    ['2024-07-02', 'Sally', 34.12],
];

foreach ($rows as $row) {
    $sheet->addRow($row);
}

// Save as Excel file in memory
$file = new ZipDeflateStream();
$workbook->save($file);

仅生成内存中Excel文件

此数据是一个纯内存流php://memory(默认),无论写入多少数据,都不会溢出到硬盘。

use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream();
$workbook->save($file);

生成临时文件

php://temp流专为内存中的临时数据存储设计。

然而,如果写入的数据量超过一定阈值(通常在2KB或8KB左右,取决于PHP版本和配置),PHP可能会自动切换到使用磁盘上的临时文件来存储数据。这是为了在处理大量数据时节省内存。

此类流适用于大多数需要临时内存存储的场景,但当它超过一定阈值时,应自动切换到使用磁盘上的临时文件来存储多余数据。

use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream('php://temp');
$workbook->save($file);

可以通过附加/maxmemory:NN来控制php://temp的内存限制,其中NN是使用临时文件之前在内存中保持的最大数据量,以字节为单位。

此可选参数允许在php://temp开始使用临时文件之前设置内存限制。

use Odan\Excel\ZipDeflateStream;

// ...

// Set the limit to 5 MB.
$maxMb = 5 * 1024 * 1024;
$file = new ZipDeflateStream('php://temp/maxmemory:' . $maxMb);
$workbook->save($file);

在文件系统中保存文件

如果文件不存在,则创建它。如果它已存在,则在向其中写入数据时将内容截断(清除)。请确保服务器具有写权限。

直接作为文件流...

use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream('example.xlsx');
$workbook->save($file);

...或使用stream_get_contents。

use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream();
$workbook->save($file);

$data = stream_get_contents($file->getStream());
file_put_contents('filename.xlsx', $data);

在硬盘上生成具有写权限的Excel文件

use Odan\Excel\ZipDeflateStream;

// ...

$filename = 'example.xlsx';

// Create an empty file using touch
touch($filename);

// Set write permissions to the file
chmod($filename, 0644);

$file = new ZipDeflateStream($filename);
$workbook->save($file);

将流内容作为字符串读取

use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream();
$workbook->save($file);

// Read contents of stream into a string
$data = stream_get_contents($file->getStream());

直接将流发送到HTTP响应

要直接将现有流发送到HTTP响应,可以使用fpassthru函数。此函数从打开的文件指针读取内容,并将其直接发送到输出缓冲区。

以下是如何做到这一点的示例

<?php

// Set the content type to Excel
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="example.xlsx"');

// ...
$stream = $file->getStream();

// Send the stream contents directly to the HTTP response
fpassthru($stream);

// Close the stream
fclose($stream);

直接将流发送到PSR-7 HTTP响应

要使用Nyholm PSR-7包直接将文件流到PSR-7 HTTP响应,您可以按照以下方式使用它

use Nyholm\Psr7\Response;
use Nyholm\Psr7\Stream;
use Odan\Excel\ZipDeflateStream;

// ...

$file = new ZipDeflateStream();
$workbook->save($file);

// Generate safe filename
$outputFilename = rawurlencode(basename('example.xlsx'));
$contentDisposition = sprintf("attachment; filename*=UTF-8''%s", $outputFilename);

// Add the response headers
$response = $response
    ->withHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    ->withHeader('Content-Disposition', $contentDisposition)
    ->withHeader('Pragma', 'private')
    ->withHeader('Cache-Control', 'private, must-revalidate')
    ->withHeader('Content-Transfer-Encoding', 'binary');

// Set the response body to the file stream
$response = $response->withBody(new Stream($file->getStream()));

相应地更改文件名。

使用ZipStream-PHP包

当处理非常大的Excel文件(通常超过4GB)时,可以使用ZipStream-PHP包来创建ZIP64格式的Excel文件,该格式专为处理此类大文件而设计。

安装

composer require maennchen/zipstream-php

接下来,使用 Odan\Excel\Zip64Stream 类来创建具有改进兼容性和支持更大文件大小的 Excel 文件。

use Odan\Excel\ExcelWorkbook;
use Odan\Excel\Zip64Stream;

$workbook = new ExcelWorkbook();
$sheet = $workbook->addSheet('My Sheet');

// Write data
$rows = [
    ['2023-01-31', 'James', 220],
    ['2023-03-28', 'Mike', 153.5],
    ['2024-07-02', 'Sally', 34.12],
];

foreach ($rows as $row) {
    $sheet->addRow($row);
}

// Save as Excel file
$file = new Zip64Stream('filename.xlsx');
$workbook->save($file);

许可证

MIT 许可证(MIT)。有关更多信息,请参阅许可证文件