将Excel表格导出为csv格式,并使用fgetcsv函数将其转换为php文件

4

我正在使用Excel 2010专业增强版创建一个Excel文件。 之后,我尝试将其导出为UTF-8 .csv文件。 我通过将其保存为CSV(符号分隔.....抱歉,我不知道确切的措辞)来实现这一点。 然后我点击工具->网页选项并选择Unicode(UTF-8)作为编码。 示例.csv如下:

ID;englishName;germanName
1;Austria;Österreich

到目前为止一切都很好,但是如果我现在用我的php代码打开这个文件:
 header('Content-Type: text/html; charset=UTF-8');
 iconv_set_encoding("internal_encoding", "UTF-8");
 iconv_set_encoding("output_encoding", "UTF-8");
 setlocale(LC_ALL, 'de_DE.utf8');
 $fp=fopen($filePathName,'r');
 while (($dataRow= fgetcsv($fp,0,";",'"') )!==FALSE)
 {
     print_r($dataRow);
 }
  • 我在屏幕上得到了结果为“�sterreich”(因为这是“错误”,我剪切了结果的所有其他部分)。
  • 如果我用notepad++打开文件并查看编码,我会看到“ANSI”而不是UTF-8。
  • 如果我在notepad++中更改编码为UTF8...那么ö,ä等字符将被特殊字符替换,我必须手动更正。

如果我采用另一种方式,在notepad++中创建一个新的UTF-8文件,并输入与Excel文件中相同的数据,当我使用php文件打开它时,屏幕上显示的是“Österreich”。

现在我的问题是,为什么它在Excel中不能正常工作,我做错了什么?还是我忽略了某些东西?

编辑: 由于该程序最终将安装在客户提供的Windows服务器上, 需要找到一种解决方案,无需安装额外的工具(PHP库可以,但需要安装vm-ware或cygwin之类的工具不行)。 此外,服务器上不会本地安装Excel(或Office),因为客户将能够通过文件上传对话框上传.csv文件(对话框本身不是问题所在,因为我知道如何处理这些)。此外,我在测试机器上创建一个Excel文件并将其转换为.csv时遇到的问题本身)。

Tnx

5个回答

11

来自 PHP DOC

此函数会考虑语言环境设置。如果 LANG 是例如 en_US.UTF-8,那么此函数将错误地读取单字节编码的文件

您可以尝试

header('Content-Type: text/html; charset=UTF-8');
$fp = fopen("log.txt", "r");
echo "<pre>";
while ( ($dataRow = fgetcsv($fp, 1000, ";")) !== FALSE ) {
    $dataRow = array_map("utf8_encode", $dataRow);
    print_r($dataRow);
}

输出

Array
(
    [0] => ID
    [1] => englishName
    [2] => germanName
)
Array
(
    [0] => 1
    [1] => Austria
    [2] => Österreich
)

array_map是解决方案,谢谢。 没想到如果我已经告诉程序我正在读取的是UTF-8,我还需要显式地将其映射为UTF-8。 (有趣的现象.....除了Excel将其导出为ANSI)再次感谢。 - Thomas

1

对于来自捷克共和国的人:

function convert( $str ) {
    return iconv( "CP1250", "UTF-8", $str );
}
...
while (($data = fgetcsv($this->fhandle, 1000, ";")) !== FALSE) {
$data = array_map( "convert", $data );
...

1

我不知道为什么Excel生成的是ANSI文件而不是UTF-8(如Notepad++所示),但如果是这种情况,您可以使用iconv转换文件:

iconv --from-code=ISO-8859-1 --to-code=UTF-8 my_csv_file.csv > my_csv_file_utf8.csv


1
有没有其他方法可以做到这一点,而不依赖于Unix命令?(该应用程序应能够在相当多的不同Windows机器上运行,而无需安装其他工具,因此在那些服务器上安装允许我使用Unix命令的工具并不是一件好事)。 - Thomas

0

从你的说法来看,我怀疑Excel写入了一个没有BOM的UTF-8文件(without BOM),这使得猜测编码是否为utf-8变得更加棘手。如果在Notepad++中按下格式->以UTF-8(无BOM)编码(而不是格式->转换为UTF-8(无BOM)),字符显示正确,你可以确认这个诊断。

你确定每个用户都会使用UTF-8吗?听起来你需要一些能够智能猜测实际输入编码的东西。所谓“智能”,就是指这种猜测能够识别没有BOM的UTF-8。

为了简化问题,我会做以下操作:

$f = fopen('file.csv', 'r');

while( ($row = fgets($f)) != null )
    if( mb_detect_encoding($row, 'UTF-8', true) !== false )
        var_dump(str_getcsv( $row, ';' ));
    else
        var_dump(str_getcsv( utf8_encode($row), ';' ));

fclose($f);

这是有效的,因为你读取字符以猜测编码,而不是懒惰地信任前3个字符:因此UTF-8无BOM仍将被识别为UTF-8。当然,如果你的csv文件不太大,你可以在整个文件内容上进行编码检测:类似于mb_detect_encoding(file_get_contents(...), ...)


对于Excel。我使用Notepad++检查了文件。Notepad++告诉我它们仍然是ANSI编码(即使导出为UTF8)。当我将用Notepad++创建的UTF8编码文件导入Excel时,好像有错误的编码(我得到特殊字符而不是ö、ü等)。 - Thomas
@ThomasE。无论如何,这个解决方案应该是可行的。而且它应该能够处理非UTF8输入。它与Baba的解决方案并没有太大区别,因为它将utf8_encode应用于从有问题的csv文件中导入的字符串。 - Cimbali

0
问题必须是您的文件编码,看起来它不是UTF-8。
当我尝试了您的示例并双重检查文件确实是UTF-8时,它对我有效,我得到:
Array([0] => 1 [1] =>奥地利[2] => Österreich)
使用LibreOffice(OpenOffice),它在这些事情上更可靠。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接