【问题标题】:Is there any way I can ease Excel's UTF-8 handling using PHP?有什么方法可以使用 PHP 简化 Excel 的 UTF-8 处理?
【发布时间】:2016-08-03 04:38:31
【问题描述】:

我在几个脚本中遇到了一些非常特殊的 UTF-8 行为,这些脚本通过 CSV 文件将信息导入/导出到数据库,尤其是 Excel 处理它们的方式。

脚本本身并不是特别复杂,我相信我正确设置了编码(为简洁起见,我排除了错误处理和字符转义代码):

导入

header("Content-Type: text/plain; charset=UTF-8");

require_once("inc.db.php"); // database connection
mysql_query("SET NAMES utf8");

$csv = $_FILES['csv'];
$handle = fopen($csv['tmp_name'], "r");

while ($data = fgetcsv($handle, 1000, ',', '"')) {
    $first_name = $data[0];
    $family_name = $data[1];
    $company = $data[2];
    mysql_query("INSERT INTO table SET first_name = '$first_name', etc...);
}

导出

header("Content-Type: text/csv; charset=UTF-8");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");

echo "\xEF\xBB\xBF"); // utf-8 bom
setlocale(LC_ALL, "en_US.UTF8");

require_once("inc.db.php"); // database connection
mysql_query("SET NAMES utf8");

echo "FIRST NAME,FAMILY NAME,COMPANY,\n";

$query = mysql_query("SELECT first_name, family_name, company FROM table");
while ($data = mysql_fetch_assoc($query)) {
    echo '"' . $first_name . '","' . $family_name. '","' . $company. '",\n';
}

// Alternate attempt at looping below

$array = array();
while ($data = mysql_fetch_assoc($query)) {
    $array[] = $data;
}
$x = fopen("php://output", "w");
foreach ($array as $fields) {
    fputcsv($x, $fields);
}
fclose($x);

在我看来,这两个脚本都运行良好,到目前为止没有问题。然而,当我在 Excel 中打开并处理导出的 CSV 文件时,有趣的事情就从这里开始了。

数据库中的信息包含外来拉丁字符,如éÜ。这些存储正确(MySQL数据库编码为utf8_unicode_ci),仍然没有问题。

但是,这三个方案中只有两个可以正常工作。但是你猜怎么着,不工作的那个(场景二)是我需要工作的那个……不总是这样吗?


场景一

我导出一个 CSV 文件,然后立即重新导入。我从不以任何方式打开或修改文件。

不幸的是,这是一个毫无意义的练习。不过,它确实有效。


场景二

我导出一个 CSV 文件,打开它,修改内容,保存,然后重新导入。

有趣的提示:当我从 Excel 的对话框菜单中选择“保存”时,它会保存为“Unicode 文本”文件,而不是覆盖 CSV 文件。此新文件仍可在 Excel 中打开,但数据已损坏。我需要选择“另存为...”并从文件类型菜单中选择“逗号分隔值”。我也尝试在这一步的编码菜单中选择 UTF-8。

这种情况的问题在于外来字符:一旦导入脚本到达其中一个,它就会停止将该字段写入数据库。没有损坏的字符â€。没有小问号。简单地说,什么都没有。但是,CSV 的那一行中的其余数据写得很好。


场景三

我导出一个 CSV 文件,打开它,修改内容,保存,在文本编辑器中打开,使用 UTF-8 编码重新保存,然后重新导入。

万岁,它有效!但是,我不能指望这个系统的用户使用文本编辑器和编码——他们应该能够无缝地导出 > 编辑 > 保存 > 导入。


我对出了什么问题的看法™

  1. 我的一个脚本(可能是导入)中的某些内容未正确处理编码。
  2. 我的一个脚本(可能是导出)中的某些内容未正确创建 CSV 文件,因此保存对话框中的 Unicode 文本文件类型。
  3. Excel 只是真的不喜欢 UTF-8 文件,我无能为力。

请告诉我这是我的错,我有办法解决这个问题!

【问题讨论】:

  • 您是在 Mac 还是 Windows 上使用 Excel?我知道与使用不同编码的 Windows 相比,Mac 上的 Excel 存在一些问题。
  • 这是在 Windows、Office 2010 和 2013 上。

标签: php excel csv encoding utf-8


【解决方案1】:

在 Windows Excel 中,Unicode Text 另存为选项会写出一个制表符分隔的 unicode 文件,但 Windows 就是这样,它以 UTF16 格式写入。您的导入可能预期 UTF-8,因此一旦它遇到奇怪的 2 字节 UTF-16LE 编码的外来字符,它就会对自己产生呕吐并放弃。

您可以使用 linux 命令 iconv -f UTF-16LE -t utf8 yourfile.address > yourfile.address.tmp 进行转换,或更改您的导入脚本以接受 UTF-16LE 编码的数据。

【讨论】:

  • 问题是,当我另存为时,我将其切换回逗号分隔类型。
  • iconv()mb_convert_encoding() 函数都不起作用。
  • 所以你在 Excel 中打开文件,然后另存为 Unicode 文本,然后再次打开它?如果您再次打开它并另存为 CSV,它将不再是 unicode。在 excel 中,至少根据我的经验,您无法将文件导出为逗号分隔和 unicode。所以我导出为 Unicode,然后用另一个程序交换分隔符并将 utf16le 转换为 utf8。另一方面,LibreOffice Calc 允许您在导出时指定编码和分隔符,因此您最好切换到该程序。
  • 不,第一次打开文件并直接保存到逗号分隔的文件中。我从不处理 unicode 文本文件——当我选择另存为时,它只是“另存为类型”下拉菜单中的默认选择选项。
  • 是的。 Excel 对 unicode 和导出分隔符不友好 :(。我有一个流程供从国外向我发送 unicode 数据的人使用。他们主要在 Excel 中工作,而不是技术人员,所以我只是让他们“另存为... Unicode 文本”在 Excel 中,然后我有一个 bash 脚本,它交换管道的选项卡,清除双引号字符串封装,并将文件从 UTF-16LE 转换为 UTF8,然后我导入它。我感到你的痛苦。跨度>
猜你喜欢
  • 1970-01-01
  • 2022-10-18
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 2013-05-27
相关资源
最近更新 更多