2019年10月11日14:05:58
读写文件从体系结构您已经知道,使用基本PhpSpreadsheet类无法对持久性存储进行读写。
为此,PhpSpreadsheet提供读者和作家,这是实现\PhpOffice\PhpSpreadsheet\Reader\IReader
和 \PhpOffice\PhpSpreadsheet\Writer\IWriter
。
PhpSpreadsheet API提供了多种创建 \PhpOffice\PhpSpreadsheet\Reader\IReader
或 \PhpOffice\PhpSpreadsheet\Writer\IWriter
实例的方法:
通过直接创建\PhpOffice\PhpSpreadsheet\IOFactory
。
下面的所有示例都演示了直接创建方法。
请注意,您也可以使用\PhpOffice\PhpSpreadsheet\IOFactory
该类来执行此 *** 作。
\PhpOffice\PhpSpreadsheet\Reader\IReader
使用创建\PhpOffice\PhpSpreadsheet\IOFactory
有两种方法可以将文件读入PhpSpreadsheet:使用自动文件类型解析或显式。
自动文件类型解析可\PhpOffice\PhpSpreadsheet\Reader\IReader
使用PhpSpreadsheet 检查不同的 分布。
如果其中之一可以加载指定的文件名,则使用该文件名加载文件\PhpOffice\PhpSpreadsheet\Reader\IReader
。
显式模式要求您指定 \PhpOffice\PhpSpreadsheet\Reader\IReader
应使用的模式。
您可以使用以下代码示例在自动文件类型解析模式下创建\PhpOffice\PhpSpreadsheet\Reader\IReader
实例 \PhpOffice\PhpSpreadsheet\IOFactory
:
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("05featuredemo.xlsx");
此功能的典型用法是当您需要读取用户上传的文件时,并且您不知道他们是在上传xls还是xlsx文件。
如果您需要在阅读器上设置一些属性(例如,仅读取数据,请参阅稍后的更多内容),则可以改用以下变体:
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("05featuredemo.xlsx");
$reader->setReadDataOnly(true);
$reader->load("05featuredemo.xlsx");
您可以使用以下代码示例以显式模式使用创建\PhpOffice\PhpSpreadsheet\Reader\IReader
实例 \PhpOffice\PhpSpreadsheet\IOFactory
:
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader("Xlsx");
$spreadsheet = $reader->load("05featuredemo.xlsx");
请注意,自动类型解析模式比显式模式稍慢。
\PhpOffice\PhpSpreadsheet\Writer\IWriter
使用创建\PhpOffice\PhpSpreadsheet\IOFactory
您可以\PhpOffice\PhpSpreadsheet\Writer\IWriter
使用创建实例 \PhpOffice\PhpSpreadsheet\IOFactory
:
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, "Xlsx");
$writer->save("05featuredemo.xlsx");
Excel 2007(SpreadsheetML)文件格式
Xlsx文件格式是PhpSpreadsheet的主要文件格式。
它允许将内存电子表格输出到.xlsx文件。
您可以使用以下代码读取.xlsx文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadsheet = $reader->load("05featuredemo.xlsx");
仅读取数据
您可以在阅读器上设置选项setReadDataOnly,以指示阅读器忽略样式,数据验证等,而仅读取单元格数据:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load("05featuredemo.xlsx");
仅阅读特定的工作表
您可以在阅读器上设置选项setLoadSheetsOnly,以指示阅读器仅加载具有给定名称的图纸:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
$spreadsheet = $reader->load("05featuredemo.xlsx");
仅读取特定的单元格
您可以在阅读器上设置选项setReadFilter,以指示阅读器仅加载与给定规则匹配的单元格。
读取过滤器可以是任何实现的类 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
。
默认情况下,使用读取所有单元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter
。
以下代码将仅读取Excel文件中任何工作表的第1行和第20至30行:
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xlsx");
\ PhpOffice \ PhpSpreadsheet \ Writer \ Xlsx
编写电子表格
您可以使用以下代码编写.xlsx文件:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save("05featuredemo.xlsx");
公式预计算
默认情况下,该编写器会预先计算电子表格中的所有公式。
在大型电子表格上,这可能会很慢,甚至可能是不必要的。
但是,您可以禁用公式预计算:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.xlsx");
Office 2003兼容性包
由于Office2003兼容性包中的错误,打开Xlsx电子表格时可能会出现一些小问题(主要与公式计算有关)。
您可以使用以下代码启用Office2003兼容性:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->setOffice2003Compatibility(true);
$writer->save("05featuredemo.xlsx");
Office2003兼容性仅应在需要时使用 Office2003兼容性选项应仅在需要时使用。
此选项禁用多个Office2007文件格式选项,从而导致使用该选项时功能较低的Office2007电子表格。
Xls文件格式是旧的Excel文件格式,已在PhpSpreadsheet中实现,以提供统一的方式来创建.xlsx和.xls文件。
它基本上是PEAR Spreadsheet_Excel_Writer的修改版本,尽管它已被扩展并且比旧的PEAR库具有更少的限制和更多的功能。
这可以通过BIFF8读取所有使用OLE2的BIFF版本:BIFF5(由Office 95引入),但不能读取早期版本。
Xls文件格式将不再进行开发,它只是为PhpSpreadsheet提供了其他文件格式。
Excel5(BIFF)限制请注意,BIFF文件格式在样式设置单元格和通过PHP处理大型电子表格方面有一些限制。
您可以使用以下代码读取.xls文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$spreadsheet = $reader->load("05featuredemo.xls");
仅读取数据
您可以在阅读器上设置选项setReadDataOnly,以指示阅读器忽略样式,数据验证等,而仅读取单元格数据:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load("05featuredemo.xls");
仅阅读特定的工作表
您可以在阅读器上设置选项setLoadSheetsOnly,以指示阅读器仅加载具有给定名称的图纸:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setLoadSheetsOnly(["Sheet 1", "My special sheet"]);
$spreadsheet = $reader->load("05featuredemo.xls");
仅读取特定的单元格
您可以在阅读器上设置选项setReadFilter,以指示阅读器仅加载与给定规则匹配的单元格。
读取过滤器可以是任何实现的类 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
。
默认情况下,使用读取所有单元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter
。
以下代码将仅读取Excel文件中任何工作表的第1行和第20至30行:
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xls");
\ PhpOffice \ PhpSpreadsheet \ Writer \ Xls
编写电子表格
您可以使用以下代码编写.xls文件:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);
$writer->save("05featuredemo.xls");
Excel 2003 XML文件格式
Excel 2003 XML文件格式是可以在较早版本的Microsoft Excel中使用的文件格式。
Excel 2003 XML限制请注意,Excel 2003 XML格式在样式设置单元格和通过PHP处理大型电子表格方面有一些限制。
您可以使用以下代码读取Excel 2003 .xml文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
$spreadsheet = $reader->load("05featuredemo.xml");
仅读取特定的单元格
您可以在阅读器上设置选项setReadFilter,以指示阅读器仅加载与给定规则匹配的单元格。
读取过滤器可以是任何实现的类 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
。
默认情况下,使用读取所有单元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter
。
以下代码将仅读取Excel文件中任何工作表的第1行和第20至30行:
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.xml");
象征性LinK(SYLK)
符号链接(SYLK)是Microsoft文件格式,通常用于在应用程序(尤其是电子表格)之间交换数据。
SYLK文件通常具有.slk后缀。
它仅由可显示的ANSI字符组成,可以很容易地由其他应用程序(例如数据库)创建和处理。
SYLK限制请注意,SYLK文件格式在样式设置单元格和通过PHP处理大型电子表格方面有一些限制。
您可以使用以下代码读取.slk文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
$spreadsheet = $reader->load("05featuredemo.slk");
仅读取特定的单元格
您可以在阅读器上设置选项setReadFilter,以指示阅读器仅加载与给定规则匹配的单元格。
读取过滤器可以是任何实现的类 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
。
默认情况下,使用读取所有单元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter
。
以下代码将仅读取SYLK文件中任何工作表的第1行和第20至30行:
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.slk");
开放/自由办公室(.ods)
Open Office或Libre Office .ods文件是Open Office或Libre Office Calc文件的标准文件格式。
您可以使用以下代码读取.ods文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
$spreadsheet = $reader->load("05featuredemo.ods");
仅读取特定的单元格
您可以在阅读器上设置选项setReadFilter,以指示阅读器仅加载与给定规则匹配的单元格。
读取过滤器可以是任何实现的类 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
。
默认情况下,使用读取所有单元格\PhpOffice\PhpSpreadsheet\Reader\DefaultReadFilter
。
以下代码将仅读取Calc文件中任何工作表的第1行和第20至30行:
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter {
public function readCell($column, $row, $worksheetName = '') {
// Read title row and rows 20 - 30
if ($row == 1 || ($row >= 20 && $row <= 30)) {
return true;
}
return false;
}
}
$reader = new PhpOffice\PhpSpreadsheet\Reader\Ods();
$reader->setReadFilter( new MyReadFilter() );
$spreadsheet = $reader->load("06largescale.ods");
CSV(逗号分隔值)
CSV(逗号分隔值)通常与其他系统一起用作导入/导出文件格式。
PhpSpreadsheet允许读取和写入CSV文件。
CSV限制请注意,CSV文件格式在样式单元格,数字格式等方面有一些限制。
您可以使用以下代码读取.csv文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$spreadsheet = $reader->load("sample.csv");
设置CSV选项
CSV文件通常不是真正的“逗号分隔”,或使用分号(;
)作为分隔符。
您可以\PhpOffice\PhpSpreadsheet\Reader\Csv
在读取CSV文件之前指示 一些选项。
分隔符将被自动检测,因此在大多数情况下,无需指定分隔符。
但是,如果自动检测不适合用例,则可以手动设置。
请注意,\PhpOffice\PhpSpreadsheet\Reader\Csv
默认情况下假定加载的CSV文件是UTF-8编码的。
如果要读取在Microsoft Office Excel中创建的CSV文件,则正确的输入编码可能是Windows-1252(CP1252)。
始终确保正确设置了输入编码。
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$reader->setInputEncoding('CP1252');
$reader->setDelimiter(';');
$reader->setEnclosure('');
$reader->setSheetIndex(0);
$spreadsheet = $reader->load("sample.csv");
阅读特定的工作表
CSV文件只能包含一个工作表。
因此,您可以指定要从CSV中读取的工作表:
$reader->setSheetIndex(0);
读入现有电子表格
使用CSV文件时,可能会出现要将CSV数据导入到现有Spreadsheet
对象中的情况。
以下代码将CSV文件加载到$spreadsheet
包含某些工作表的现有文件中,并导入到第6个工作表中:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$reader->setDelimiter(';');
$reader->setEnclosure('');
$reader->setSheetIndex(5);
$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
\ PhpOffice \ PhpSpreadsheet \ Writer \ Csv
编写CSV文件
您可以使用以下代码编写.csv文件:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->save("05featuredemo.csv");
设置CSV选项
CSV文件通常不是真正的“逗号分隔”,或使用分号(;
)作为分隔符。
您可以\PhpOffice\PhpSpreadsheet\Writer\Csv
在编写CSV文件之前指示 一些选项:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setDelimiter(';');
$writer->setEnclosure('');
$writer->setLineEnding("\r\n");
$writer->setSheetIndex(0);
$writer->save("05featuredemo.csv");
写一个特定的工作表
CSV文件只能包含一个工作表。
因此,您可以指定要写入CSV的工作表:
$writer->setSheetIndex(0);
公式预计算
默认情况下,该编写器会预先计算电子表格中的所有公式。
在大型电子表格上,这可能会很慢,甚至可能是不必要的。
但是,您可以禁用公式预计算:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.csv");
写入UTF-8 CSV文件
通过编写BOM表文件头,可以将CSV文件标记为UTF-8。
可以使用以下代码启用此功能:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setUseBOM(true);
$writer->save("05featuredemo.csv");
十进制和千位分隔符
如果要导出的工作表包含带小数或千位分隔符的数字,则在进行导出之前,应考虑要对那些字符使用哪些字符。
默认情况下,PhpSpreadsheet在服务器的区域设置中查找以决定要使用的字符。
但是为避免出现问题,建议如下所示显式设置字符。
英文用户将要在导出之前使用它:
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator('.');
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator(',');
德国用户将要使用相反的值。
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setDecimalSeparator(',');
\PhpOffice\PhpSpreadsheet\Shared\StringHelper::setThousandsSeparator('.');
请注意,上面的代码将小数和千位分隔符设置为全局选项。
这也会影响HTML和PDF的导出方式。
PhpSpreadsheet允许您以HTML格式读取或写入电子表格,以便向PC上没有电子表格应用程序的任何人快速表示其中的数据,或加载由其他脚本保存的文件,这些脚本只是创建HTML标记并为其提供.xls文件扩展。
HTML限制请注意,HTML文件格式在样式单元格,数字格式等方面有一些限制。
您可以使用以下代码读取.html或.htm文件:
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->load("05featuredemo.html");
HTML限制请注意,HTML阅读器仍处于试验阶段,尚不支持干净的合并单元格或嵌套表
\ PhpOffice \ PhpSpreadsheet \ Writer \ Html请注意,\PhpOffice\PhpSpreadsheet\Writer\Html
默认情况下仅输出第一个工作表。
您可以使用以下代码编写.htm文件:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->save("05featuredemo.htm");
编写所有工作表
HTML文件可以包含一个或多个工作表。
如果要将所有工作表都写到一个HTML文件中,请使用以下代码:
$writer->writeAllSheets();
写一个特定的工作表
HTML文件可以包含一个或多个工作表。
因此,您可以指定要写入HTML的工作表:
$writer->setSheetIndex(0);
设置HTML文件的图片根目录
在某些情况下,您需要显式设置所包含映像的根目录。
例如,代替:
html <img src="./images/logo.jpg">
您可能想看看:
<img src="http://www.domain.com/images/logo.jpg">
您可以使用以下代码来实现此结果:
$writer->setImagesRoot('http://www.example.com');
公式预计算
默认情况下,该编写器会预先计算电子表格中的所有公式。
在大型电子表格上,这可能会很慢,甚至可能是不必要的。
但是,您可以禁用公式预计算:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.htm");
将生成的HTML嵌入网页中
在某些情况下,您可能希望将生成的HTML嵌入到现有网站中。
\ PhpOffice \ PhpSpreadsheet \ Writer \ Html支持仅生成HTML代码的特定部分,从而使您可以在网站中使用这些部分。
支持的方法:
generateHTMLHeader()
generateStyles()
generateSheetData()
generateHTMLFooter()
这是一个示例,该示例独立地检索所有部分并将它们合并到结果HTML页面中:
<?php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
echo $writer->generateHTMLHeader();
?>
<style>
<!--
html {
font-family: Times New Roman;
font-size: 9pt;
background-color: white;
}
<?php
echo $writer->generateStyles(false); // do not write <style> and </style>
?>
-->
</style>
<?php
echo $writer->generateSheetData();
echo $writer->generateHTMLFooter();
?>
编写UTF-8 HTML文件
通过编写BOM表文件头,可以将HTML文件标记为UTF-8。
可以使用以下代码启用此功能:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Html($spreadsheet);
$writer->setUseBOM(true);
$writer->save("05featuredemo.htm");
十进制和千位分隔符
请参阅“ \PhpOffice\PhpSpreadsheet\Writer\Csv
如何控制它们的外观”部分。
PhpSpreadsheet允许您将电子表格写入PDF格式,以快速分发表示的数据。
PDF限制请注意,PDF文件格式在样式单元格,数字格式等方面有一些限制。
PhpSpreadsheet的PDF Writer是第三方PDF渲染库(如TCPDF,mPDF或Dompdf)的包装。
现在,您必须自己安装PDF渲染库。
但PhpSpreadsheet可以与许多不同的库一起使用。
当前,支持以下库:
不同的库具有不同的优点和缺点。
有些生成比其他格式更好的格式输出,有些比其他格式更快或使用更少的内存,而有些生成较小的.pdf文件。
他们希望根据自己的情况使用的是开发人员的选择。
您可以使用其特定名称实例化writer,如下所示:
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
或者,您可以使用更通用的名称注册正在使用的编写器,因此您不必记住选择的是哪个库,而只需要编写PDF文件即可:
$class = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', $class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
或者,您可以像这样直接实例化您选择的作者:
$writer = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
定制实施或配置
如果需要受支持的PDF库的自定义实现或自定义配置。
您可以扩展PDF库和PDF编写器,如下所示:
class My_Custom_TCPDF extends TCPDF
{
// ...
}
class My_Custom_TCPDF_Writer extends \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf
{
protected function createExternalWriterInstance($orientation, $unit, $paperSize)
{
$instance = new My_Custom_TCPDF($orientation, $unit, $paperSize);
// more configuration of $instance
return $instance;
}
}
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', MY_TCPDF_WRITER::class);
编写电子表格
一旦确定了要用于PDF生成的渲染器,就可以使用以下代码编写.pdf文件:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->save("05featuredemo.pdf");
请注意,\PhpOffice\PhpSpreadsheet\Writer\Pdf
默认情况下仅输出第一个工作表。
PDF文件可以包含一个或多个工作表。
如果要将所有工作表都写到一个PDF文件中,请使用以下代码:
$writer->writeAllSheets();
写一个特定的工作表
PDF文件可以包含一个或多个工作表。
因此,您可以指定要写入PDF的工作表:
$writer->setSheetIndex(0);
公式预计算
默认情况下,该编写器会预先计算电子表格中的所有公式。
在大型电子表格上,这可能会很慢,甚至可能是不必要的。
但是,您可以禁用公式预计算:
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.pdf");
十进制和千位分隔符
请参阅“ \PhpOffice\PhpSpreadsheet\Writer\Csv
如何控制它们的外观”部分。
读写器是使您能够从模板生成Excel文件的工具。
与从头开始生成Excel文件相比,这需要更少的编码工作,尤其是在您的模板具有许多样式,页面设置属性,标题等的情况下。
这是一个如何打开模板文件,填写几个字段并再次保存的示例:
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load('template.xlsx');
$worksheet = $spreadsheet->getActiveSheet();
$worksheet->getCell('A1')->setValue('John');
$worksheet->getCell('A2')->setValue('Smith');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');
请注意,可以加载一个xlsx文件并生成一个xls文件。
如果要从预渲染的HTML内容生成Excel文件,则可以使用HTML Reader自动进行。
当您从将下载/发送给用户的Web应用程序内容生成Excel文件时,此功能非常有用。
例如:
$htmlString = '<table>
<tr>
<td>Hello World</td>
</tr>
<tr>
<td>Hello<br />World</td>
</tr>
<tr>
<td>Hello<br>World</td>
</tr>
</table>';
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Html();
$spreadsheet = $reader->loadFromString($htmlString);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');
读取文件
安全
在读取电子表格文件时,基于XML的格式(例如OfficeOpen XML,Excel2003 XML,OASIS和Gnumeric)容易受到XML外部实体处理(XXE)注入攻击。
这可能导致:
- 披露文件是否存在
- 服务器端请求伪造
- 命令执行(取决于已安装的PHP包装器)
为了防止这种情况,默认情况下,每个基于XML的阅读器都将在DOCTYPE中声明的XML实体进行查找,如果发现任何实体,则会引发异常。
阅读有关XXE注射的更多信息。
加载工作簿文件的最简单方法是让PhpSpreadsheet的IO Factory识别文件类型并加载它,并调用该类的静态load()
方法\PhpOffice\PhpSpreadsheet\IOFactory
。
$inputFileName = './sampleData/example1.xls';
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
有关samples/Reader/01_Simple_file_reader_using_IOFactory.php
该代码的有效示例,请参见。
该load()
方法将尝试识别文件类型,并为该文件类型实例化加载程序;使用它来加载文件并在Spreadsheet
对象中存储数据和任何格式。
该方法根据文件扩展名对加载器进行初始猜测以实例化;但会在实际执行加载之前测试该文件:因此,例如,如果该文件实际上是CSV文件或包含HTML标记,但已赋予.xls扩展名(很常见),它将拒绝Xls通常用于.xls文件的加载程序;并使用其他加载程序测试文件,直到找到合适的加载程序,然后使用该文件读取文件。
虽然很容易在代码中实现,但您不必担心文件类型;这不是加载文件的最有效方法;而且它缺乏在实际将文件读入Spreadsheet
对象之前以任何方式配置加载程序的灵活性。
如果知道需要加载的电子表格文件的文件类型,则可以实例化该文件类型的新阅读器对象,然后使用阅读器的load()
方法将文件读取为Spreadsheet
对象。
可以通过名称实例化每种不同的受支持文件类型的阅读器对象。
但是,如果文件类型不正确(例如,扩展名为.xls的CSV文件),则可能会得到无法预测的结果,尽管通常应捕获此类异常。
$inputFileName = './sampleData/example1.xls';
/** Create a new Xls Reader **/
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Gnumeric();
// $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/02_Simple_file_reader_using_a_specified_reader.php
该代码的有效示例,请参见。
或者,您可以使用IO Factory的createReader()
方法为您实例化阅读器对象,只需告诉它要实例化的阅读器的文件类型即可。
$inputFileType = 'Xls';
// $inputFileType = 'Xlsx';
// $inputFileType = 'Xml';
// $inputFileType = 'Ods';
// $inputFileType = 'Slk';
// $inputFileType = 'Gnumeric';
// $inputFileType = 'Csv';
$inputFileName = './sampleData/example1.xls';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/03_Simple_file_reader_using_the_IOFactory_to_return_a_reader.php
该代码的有效示例,请参见。
如果不确定文件类型,则可以IOFactory::identify()
在使用该createReader()
方法实例化Reader对象之前,使用该方法标识所需 的阅读器。
$inputFileName = './sampleData/example1.xls';
/** Identify the type of $inputFileName **/
$inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($inputFileName);
/** Create a new Reader of the type that has been identified **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/04_Simple_file_reader_using_the_IOFactory_to_identify_a_reader_to_use.php
该代码的有效示例,请参见。
为要加载的工作簿创建阅读器对象后,您将有机会在执行该load()
方法之前设置其他选项。
如果您只对工作簿中的单元格值感兴趣,而又不需要任何单元格格式信息,则可以使用该setReadDataOnly()
方法将读取器设置为仅读取每个单元格中的数据值和任何公式 。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Advise the Reader that we only want to load cell data **/
$reader->setReadDataOnly(true);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/05_Simple_file_reader_using_the_read_data_only_option.php
该代码的有效示例,请参见。
重要的是要注意,工作簿(和PhpSpreadsheet)将日期和时间存储为简单的数字值:它们只能通过应用于该单元格的格式掩码与其他数字值区分开。
将只读数据设置为true时,PhpSpreadsheet不会读取单元格格式掩码,因此无法区分日期/时间和数字。
即使仅将读取数据设置为true,Gnumeric加载器也已编写为读取日期值的格式掩码,因此可以区分日期/时间和数字。
但是其他读者尚未实现此更改。
从电子表格文件中仅读取数据适用于读取器:
如果您的工作簿包含许多工作表,但是您仅对阅读其中一些表感兴趣,则可以使用该 setLoadSheetsOnly()
方法来标识您对阅读感兴趣的那些表。
要读取一张纸,您可以将该纸名作为参数传递给setLoadSheetsOnly()
方法。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #2';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Advise the Reader of which WorkSheets we want to load **/
$reader->setLoadSheetsOnly($sheetname);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/07_Simple_file_reader_loading_a_single_named_worksheet.php
该代码的有效示例,请参见。
如果您要阅读的不仅仅是一张纸,可以将纸名列表作为数组参数传递给该setLoadSheetsOnly()
方法。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetnames = ['Data Sheet #1','Data Sheet #3'];
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Advise the Reader of which WorkSheets we want to load **/
$reader->setLoadSheetsOnly($sheetnames);
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/08_Simple_file_reader_loading_several_named_worksheets.php
该代码的有效示例,请参见。
要将此选项重置为默认值,可以调用该setLoadAllSheets()
方法。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Advise the Reader to load all Worksheets **/
$reader->setLoadAllSheets();
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/06_Simple_file_reader_loading_all_worksheets.php
该代码的有效示例,请参见。
从文件中仅读取命名的工作表适用于读者:
如果您只对阅读工作表的一部分感兴趣,则可以编写一个筛选器类,该类标识装入程序是否应读取单个单元格。
读过滤器必须实现的 \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
接口,并且包含一个 readCell()
接受的参数的方法$column
,$row
以及 $worksheetName
,并返回一个布尔值true或false指示由这些参数确定的工作簿的小区是否应该读与否。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';
$sheetname = 'Data Sheet #3';
/** Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
public function readCell($column, $row, $worksheetName = '') {
// Read rows 1 to 7 and columns A to E only
if ($row >= 1 && $row <= 7) {
if (in_array($column,range('A','E'))) {
return true;
}
}
return false;
}
}
/** Create an Instance of our Read Filter **/
$filterSubset = new MyReadFilter();
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Tell the Reader that we want to use the Read Filter **/
$reader->setReadFilter($filterSubset);
/** Load only the rows and columns that match our filter to Spreadsheet **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/09_Simple_file_reader_using_a_read_filter.php
该代码的有效示例,请参见。
此示例不是特别有用,因为它只能在非常特殊的情况下使用(当您只希望工作表中的A1:E7范围内的单元格时。
通用的读取过滤器可能会更有用:
/** Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
class MyReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
private $startRow = 0;
private $endRow = 0;
private $columns = [];
/** Get the list of rows and columns to read */
public function __construct($startRow, $endRow, $columns) {
$this->startRow = $startRow;
$this->endRow = $endRow;
$this->columns = $columns;
}
public function readCell($column, $row, $worksheetName = '') {
// Only read the rows and columns that were configured
if ($row >= $this->startRow && $row <= $this->endRow) {
if (in_array($column,$this->columns)) {
return true;
}
}
return false;
}
}
/** Create an Instance of our Read Filter, passing in the cell range **/
$filterSubset = new MyReadFilter(9,15,range('G','K'));
有关samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php
该代码的有效示例,请参见。
通过允许您以“块”形式读取和处理大型工作簿,这对于节省内存特别有用:例如,当将数据从Excel工作表传输到数据库时,这种用法的一个例子。
$inputFileType = 'Xls';
$inputFileName = './sampleData/example2.xls';
/** Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
private $startRow = 0;
private $endRow = 0;
/** Set the list of rows that we want to read */
public function setRows($startRow, $chunkSize) {
$this->startRow = $startRow;
$this->endRow = $startRow + $chunkSize;
}
public function readCell($column, $row, $worksheetName = '') {
// Only read the heading row, and the configured rows
if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) {
return true;
}
return false;
}
}
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Define how many rows we want to read for each "chunk" **/
$chunkSize = 2048;
/** Create a new Instance of our Read Filter **/
$chunkFilter = new ChunkReadFilter();
/** Tell the Reader that we want to use the Read Filter **/
$reader->setReadFilter($chunkFilter);
/** Loop to read our worksheet in "chunk size" blocks **/
for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) {
/** Tell the Read Filter which rows we want this iteration **/
$chunkFilter->setRows($startRow,$chunkSize);
/** Load only the rows that match our filter **/
$spreadsheet = $reader->load($inputFileName);
// Do some processing here
}
有关samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_
该代码的有效示例,请参见。
使用读取过滤器适用于:
虽然您可以使用该setLoadSheetsOnly()
方法限制从工作簿文件中读取的工作表的数量,但某些阅读器还允许您将来自不同文件的多个单独的“工作表”组合到单个Spreadsheet
对象中,其中每个单独的文件都是该工作簿中的单个工作表。
对于您阅读的每个文件,您需要使用的setSheetIndex()
方法来指示应将其加载到哪个工作表索引中$reader
,然后使用 loadIntoExisting()
方法而不是将该load()
方法实际将文件读入该工作表中。
$inputFileType = 'Csv';
$inputFileNames = [
'./sampleData/example1.csv',
'./sampleData/example2.csv'
'./sampleData/example3.csv'
];
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Extract the first named file from the array list **/
$inputFileName = array_shift($inputFileNames);
/** Load the initial file to the first worksheet in a `Spreadsheet` Object **/
$spreadsheet = $reader->load($inputFileName);
/** Set the worksheet title (to the filename that we've loaded) **/
$spreadsheet->getActiveSheet()
->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
/** Loop through all the remaining files in the list **/
foreach($inputFileNames as $sheet => $inputFileName) {
/** Increment the worksheet index pointer for the Reader **/
$reader->setSheetIndex($sheet+1);
/** Load the current file into a new worksheet in Spreadsheet **/
$reader->loadIntoExisting($inputFileName,$spreadsheet);
/** Set the worksheet title (to the filename that we've loaded) **/
$spreadsheet->getActiveSheet()
->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
}
有关samples/Reader/13_Simple_file_reader_for_multiple_CSV_files.php
该代码的有效示例,请参见。
请注意,对多个工作表使用相同的工作表索引不会将文件追加到同一工作表中,但会覆盖先前加载的结果。
您不能将多个CSV文件加载到同一工作表中。
将多个文件合并为一个电子表格对象适用于:
setSheetIndex()
大型CSV文件拆分为多个工作表的方法相结合
Xls BIFF .xls文件在工作表中限制为65536行,而Xlsx Microsoft Office Open XML SpreadsheetML .xlsx文件在工作表中限制为1,048,576行;但是CSV文件不受可用磁盘空间的限制。
这意味着我们通常无法从超大型CSV文件中读取超过这些限制的所有行,并将其另存为Xls或Xlsx文件。
但是,通过使用“读取过滤器”读取“块”中的CSV文件(使用我们在上一节中定义的ChunkReadFilter类和的setSheetIndex()
方法$reader
,我们可以将CSV文件拆分为几个单独的工作表。
$inputFileType = 'Csv';
$inputFileName = './sampleData/example2.csv';
echo 'Loading file ',pathinfo($inputFileName,PATHINFO_BASENAME),' using IOFactory with a defined reader type of ',$inputFileType,'<br />';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Define how many rows we want to read for each "chunk" **/
$chunkSize = 65530;
/** Create a new Instance of our Read Filter **/
$chunkFilter = new ChunkReadFilter();
/** Tell the Reader that we want to use the Read Filter **/
/** and that we want to store it in contiguous rows/columns **/
$reader->setReadFilter($chunkFilter)
->setContiguous(true);
/** Instantiate a new Spreadsheet object manually **/
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
/** Set a sheet index **/
$sheet = 0;
/** Loop to read our worksheet in "chunk size" blocks **/
/** $startRow is set to 2 initially because we always read the headings in row #1 **/
for ($startRow = 2; $startRow <= 1000000; $startRow += $chunkSize) {
/** Tell the Read Filter which rows we want to read this loop **/
$chunkFilter->setRows($startRow,$chunkSize);
/** Increment the worksheet index pointer for the Reader **/
$reader->setSheetIndex($sheet);
/** Load only the rows that match our filter into a new worksheet **/
$reader->loadIntoExisting($inputFileName,$spreadsheet);
/** Set the worksheet title for the sheet that we've justloaded) **/
/** and increment the sheet index as well **/
$spreadsheet->getActiveSheet()->setTitle('Country Data #'.(++$sheet));
}
有关samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php
该代码的有效示例,请参见。
此代码将从我们正在加载的CSV文件中一次读取65,530行,并将每个“块”存储在新的工作表中。
在setContiguous()
这里,阅读器的方法很重要。
它仅在使用“读取过滤器”时适用,并标识是否应按单元在CSV文件中的位置或相对于过滤器的位置存储单元。
例如,如果过滤器对B2:C3范围内的单元格返回true,则将setContiguous设置为false(默认值),这些将作为B2:C3加载到Spreadsheet
对象中。
但是将setContiguous设置为true时,它们将被加载为A1:B2。
在多个工作表中拆分单个加载的文件适用于:
CSV加载程序将尝试自动检测文件中使用的分隔符。
如果无法自动检测,它将默认为逗号。
如果这不适合您的用例,则可以使用setDelimiter()
方法手动指定分隔符。
$inputFileType = 'Csv';
$inputFileName = './sampleData/example1.tsv';
/** Create a new Reader of the type defined in $inputFileType **/
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/** Set the delimiter to a TAB character **/
$reader->setDelimiter("\t");
// $reader->setDelimiter('|');
/** Load the file to a Spreadsheet Object **/
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/15_Simple_file_reader_for_tab_separated_value_file_using_the_Advanced_Value_Binder.php
该代码的有效示例,请参见。
除了定界符之外,您还可以使用以下方法来设置数据加载的其他属性:
"
UTF-8
设置CSV分隔符适用于:
从不包含格式信息的文件(例如CSV文件)中加载数据时,数据将以字符串或数字(浮点数或整数)的形式读取。
这意味着PhpSpreadsheet不会自动将日期/时间(例如16-Apr-2009
或13:30
),布尔值(true
或false
),百分比(75%
),超链接(https://www.example.com
)等识别为简单字符串以外的任何内容。
但是,可以在Value Binder的加载过程中应用针对这些值执行的其他处理。
值绑定器是实现\PhpOffice\PhpSpreadsheet\Cell\IValueBinder
接口的类 。
它必须包含一个 bindValue()
接受a \PhpOffice\PhpSpreadsheet\Cell\Cell
和一个值作为参数的方法,并返回一个布尔值true
或false
指示是否已使用该值填充工作簿单元格。
Advanced Value Binder实现了这样一个类:在其他测试中,它标识包含“ TRUE”或“ FALSE”(基于区域设置)的字符串,并将其设置为布尔值;或科学格式的数字(例如“ 1.234e-5”)并将其转换为浮点数;或日期和时间,将它们转换为Excel时间戳值–在将值存储在单元格对象中之前。
它还为标识为日期,时间或百分比的字符串设置格式。
当它遇到超链接或CSV文件中的HTML标记时,可以轻松扩展它以提供其他处理(包括文本或单元格格式)。
因此,使用Value Binder可以在读取未格式化的文本文件时在加载程序逻辑中提供更大的灵活性。
/** Tell PhpSpreadsheet that we want to use the Advanced Value Binder **/
\PhpOffice\PhpSpreadsheet\Cell\Cell::setValueBinder( new \PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder() );
$inputFileType = 'Csv';
$inputFileName = './sampleData/example1.tsv';
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
$reader->setDelimiter("\t");
$spreadsheet = $reader->load($inputFileName);
有关samples/Reader/15_Simple_file_reader_for_tab_separated_value_file_using_the_Advanced_Value_Binder.php
该代码的有效示例,请参见。
使用Value Binder进行加载适用于:
当然,您也应该始终对脚本执行一些错误处理。
PhpSpreadsheet会引发异常,因此您可以将访问库方法的所有代码包装在Try / Catch块中,以捕获遇到的任何问题,并以适当的方式进行处理。
PhpSpreadsheet读取器将引发一个 \PhpOffice\PhpSpreadsheet\Reader\Exception
。
$inputFileName = './sampleData/example-1.xls';
try {
/** Load $inputFileName to a Spreadsheet Object **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);
} catch(\PhpOffice\PhpSpreadsheet\Reader\Exception $e) {
die('Error loading file: '.$e->getMessage());
}
有关samples/Reader/16_Handling_loader_exceptions_using_TryCatch.php
该代码的有效示例,请参见。
您可以使用Reader的listWorksheetNames()
方法检索文件中包含的工作表名称列表,而无需加载整个文件。
同样,一种listWorksheetInfo()
方法将检索文件中工作表的尺寸,而无需加载和解析整个文件。
该listWorksheetNames()
方法返回一个简单的数组,列出工作簿中的每个工作表名称:
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
$worksheetNames = $reader->listWorksheetNames($inputFileName);
echo '<h3>Worksheet Names</h3>';
echo '<ol>';
foreach ($worksheetNames as $worksheetName) {
echo '<li>', $worksheetName, '</li>';
}
echo '</ol>';
有关samples/Reader/18_Reading_list_of_worksheets_without_loading_entire_file.php
该代码的有效示例,请参见。
该listWorksheetInfo()
方法返回一个嵌套数组,每个条目列出工作表的名称和尺寸:
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
$worksheetData = $reader->listWorksheetInfo($inputFileName);
echo '<h3>Worksheet Information</h3>';
echo '<ol>';
foreach ($worksheetData as $worksheet) {
echo '<li>', $worksheet['worksheetName'], '<br />';
echo 'Rows: ', $worksheet['totalRows'],
' Columns: ', $worksheet['totalColumns'], '<br />';
echo 'Cell Range: A1:',
$worksheet['lastColumnLetter'], $worksheet['totalRows'];
echo '</li>';
}
echo '</ol>';
有关samples/Reader/19_Reading_worksheet_information_without_loading_entire_file.php
该代码的有效示例,请参见
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)