8

这是我现在正在使用的。

$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
header('Content-Description: File Transfer');
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename='.basename($type.'.xlsx'));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');   
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
print "$header\n$data";
exit;

$header变量包含要生成的excel的标题行,看起来像这样

$header= "Business_Name\tBusiness_Type\tType";

\t

$data包含要在标题列下生成的行。它们也由 分隔,\t并且一行由 终止\n

当前安装文件已下载,但未使用 ms excel 打开并显示此消息。

Excel 无法打开文件“文件名”,因为文件格式或文件扩展名无效。验证文件格式没有损坏,并且文件扩展名与文件格式匹配。

应该将什么标头发送到服务器?或者我如何生成该文件?

4

3 回答 3

20

我以一种快速的、有点吝啬的方式实现了这一点——因为它冗长而曲折,我只会用概念而不是代码来解释它。

XLSX 遵循 ISO 29500,如果您想在 php 中彻底操作文档,该标准是公开的。否则,请意识到 xlsx 文件是一堆 xml 文件的压缩档案。

制作一个你想要的模板,比如它具有不同类型样式的交替行,在 excel 或某种描述的打开的 xml 编辑器中制作。确保将一些数据放在那里,并确保一些字段相等(仅用于学习目的)。

然后将文件另存为 xlsx,将其重命名为 .zip,或在存档提取器中打开并观察其内容。

首先,请注意 [Content_Types].xml 文件,它描述了存档中主要文件的位置以及它本身遵循的标准以及这些文件的内容类型。

文件夹外的所有xl/内容实际上都只是元数据。但是观察docProps/core.xml包含作者、修改和时间戳信息 - 当您重新创建此文件时,您可以在 php 中替换它们。此外,所指出的所有内容都docProps/core.xml可以根据您的口味重命名,[Content_Types].xml但不能。

好的,现在您了解了这一点,您将开始观察该地点周围的 id。他们喜欢在文件格式中使用它,所有内容都通过其在特定 xml 属性列表或类似列表中的索引来引用其他所有内容。它们通常还描述此类列表中的项目数量。

xl/你会看到themes.xml, styles.xml, workbook.xml, sharedStrings.xml, _rels/, worksheets/

样式将被大量不必要的样式夸大,如果您使用它,Excel 默认会构建这些样式。但是您应该能够看到这些样式是如何工作的,以便您可以自定义自己的样式。

主题对我来说毫无意义,所以我删除了它及其引用的 ID。

接下来您将看到工作簿,该文件包含有关电子表格文档内部工作表的信息,因为您显然可以拥有超过 1 个。它还包含一些工作表元数据,例如其大小等。

现在是你遇到的第一个大花。sharedStrings.xml是一个奇怪的文件,它存储了将插入到静态电子表格中的单元格中的所有信息。它们被编入索引,但读取文档的引擎会计算出它们的索引是什么。任何重复的内容都可以在工作表本身(工作表文件夹内)中引用回其旧索引,以节省具有重复值的大型文档中的文件大小。不是元素中的属性count和它们显然意味着什么。uniquecountsst

这是 php 中的阶段,您可以在其中填充包含工作表中所需内容的数据数组,并将其转储到 xml 格式的列表中,例如出现此文件。另请注意,这些文件不需要在没有换行符或换行符的情况下被卡住,因为有或没有仍然是有效的 xml,并且无论如何它们都可以在阅读器中工作。

查看 _rels 文件夹,它再次相当明显。

最后是表本身。此处字段中的数字是指字符串在 中的索引位置sharedStrings.xml。属性 s 是样式,t 是字段中数据的类型。R 是单元格的位置,尽管当它真的很容易弄清楚时,它为什么需要它超出了我的范围。

用 php 生成这个文件也不应该太难。只需使用用于制作sharedStrings.xml文件的数据数组中的索引即可。

哦,表格中还有列宽信息,您可以根据您使用的字体计算出它们,如果需要,也可以在 php 中自动调整它们的大小。

最后是用 php 打包它。

我的代码在一个类中,它接收我用 excel 创建的数据和特定保存的文件,以保持简单。

$this->folder_structure_simple = Array(
    "_rels/.rels" => "_rels__rels",
    "docProps/app.xml" => "docProps_app_xml",
    "docProps/core.xml" => "docProps_core_xml",
    "xl/_rels/workbook.xml.rels",
        "xl/theme/theme1.xml",
        "xl/worksheets/sheet1.xml",
        "xl/sharedStrings.xml",
        "xl/styles.xml",
        "xl/workbook.xml",
    "[Content_Types].xml" => "Content_Types_xml"
);

$zip = new ZipArchive;
$res = $zip->open($this->file_name, ZipArchive::CREATE);
if($res === TRUE){
    foreach($this->folder_structure_simple as $file => $function){
            $zip->addFromString($file, $this->$funtion);
    }
    $zip->close();
    echo 'ok';
}else{
    return FALSE;
}

函数产生所需的数据。非常快,不是很灵活。

于 2013-09-16T04:26:12.687 回答
3

您拥有的是 CSV,而不是 XLSX 文件。XLSX 是一个 ZIP 包装的 XML 块。将您的 MIME 类型更改为 text/csv。

于 2011-05-19T07:52:40.023 回答
3

你所拥有的实际上是一个 CSV 文件。根据您的操作系统、浏览器和 Excel 版本,浏览器将允许或不允许您使用 Excel 软件打开扩展 CSV、XLS XLSX。

如果您确实希望使用 Excel 打开数据,则可以使用OpenTBS将数据与 Excel 模板合并。使用当前处于候选版本中的版本 1.6.0(或更高版本),因为它为 Excel 文件带来了主要功能。

在您的标题中有“没有 excel 库 PHP”。我不知道你为什么有这个规范,但 OpenTBS 并不完全是一个 Excel 库。这是一个使用模板合并 OpenOffice 和 Ms Office 文档的 PHP 工具。

于 2011-05-27T14:43:51.230 回答