3

我知道这个问题已经讨论过好几次了,但是我在处理这个问题时变得很疯狂。我有一个带有 submit.php 操作的表单。起初我没有更改任何有关字符集的内容,我没有使用任何 utf8 标头信息。结果是我可以正确读取数据库中的所有 ä、ö、ü 等。现在将它们导出.csv到 Excel 并将它们导入 Excel UTF-8 charset(也测试了所有其他的)会导致不正确的字符集。

现在我尝试了什么:

PHP:

header("Content-Type: text/html; charset=utf-8");
$mysqli->set_charset("utf8");

MySQL:我删除了我的数据库并创建了一个新数据库:

create database db CHARACTER SET utf8 COLLATE utf8_general_ci;
create table ...

我更改了 my.cnf 并重新启动了我的 sql 服务器:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

[mysql]
default-character-set=utf8

如果我通过 bash 连接到我的数据库,我会收到以下输出:

| character_set_client     | utf8                             |
| character_set_connection | utf8                             |
| character_set_database   | utf8                             |
| character_set_filesystem | binary                           |
| character_set_results    | utf8                             |
| character_set_server     | utf8                             |
| character_set_system     | utf8                             |
| character_sets_dir       | /usr/local/mysql/share/charsets/ |

一个php测试:

var_dump($mysqli->get_charset());

给我:

Current character set: utf8 object(stdClass)#3 (8) { ["charset"]=> string(4) "utf8"     ["collation"]=> string(15) "utf8_general_ci" ["dir"]=> string(0) "" ["min_length"]=> int(1) ["max_length"]=> int(3) ["number"]=> int(33) ["state"]=> int(1) ["comment"]=> string(13) "UTF-8 Unicode" }

现在我使用:

mysql -uroot -ppw db < require.sql > /tmp/test.csv

require.sql 只是一个

select * from table;

同样,无论我选择 UTF-8 还是其他任何东西,我都无法将其作为 csv 导入 Excel。它总是给我一些加密货币..

希望有人得到提示这里可能出了什么问题..

干杯

E:TextMate 给了我一个正确的输出,所以看起来转换确实有效并且它和 Excel 问题?使用 Microsoft Office 2011。

E2:还尝试了与 latin1 相同的东西 - 同样的问题,无法将特殊字符导入 excel 而不破坏它们。任何提示或解决方法?

E3:我找到了一种解决方法,它可以使用 Excel 导入功能,但不能双击 .csv。

    iconv -f utf8 -t ISO-8859-1 test.csv > test_ISO.csv

现在我可以使用 Windows(ANSI) 将 csv 导入到 excel 中。不得不使用此功能而不是双击仍然很烦人。此外,我真的不明白为什么 UTF8 不起作用,即使是导入功能、添加的 BOM 和 UTF8 中的完整数据库也是如此。

逗号分隔也变得一团糟。1. Concat_WS 仅部分起作用,因为它在 .csv 文件中添加了一个愚蠢的 concat_ws(..) 标头。“文件 test.csv”也没有给我一个“逗号分隔”。这意味着即使所有内容都用逗号分隔,Excel 也不会在双击时注意到它。2. sed/awk:找到了一些代码片段,但它们都非常糟糕地分离了表格。例如,colum street "streetname number" 仍然是一个 'streetname','number' ,它使 2 个列从一个列中取出,并且表被搞砸了。

所以在我看来,Excel 只能通过双击打开 .csv 文件 a)使用 ISO-8859-1 编码(并且仅在 windows 下,因为标准 mac 字符集是 Macintosh)b)具有“逗号分隔”属性的文件。这意味着如果我通过 Excel 本身创建一个 .csv

file test1.csv

将会

test1.csv: ISO-8859 text, with CRLF line terminators

而使用用于添加逗号的正则表达式的 iconv 更改字符集如下所示:

test1.csv: ISO-8859 text

非常奇怪的行为 - 也许有人有一个可行的解决方案。

4

2 回答 2

0

这就是我保存从 utf-8 mysql 表中获取的数据的方式。您需要先添加 BOM。例子:

<?php
$fp = fopen(dirname(__FILE__).'/'.$filename, 'wb'); 
fputs($fp, "\xEF\xBB\xBF"); 
fputcsv($fp, array($utfstr_1,$utfstr_2);
fclose($fp);

确保你还告诉 MySQL 你将使用 UTF-8

mysql_query("SET CHARACTER SET utf8"); 
mysql_query("SET NAMES utf8"); 

您需要在选择任何数据之前执行此操作。

如果您设置语言环境,Propaply 不会很糟糕:setlocale(LC_ALL, "en_US.UTF-8");

希望能帮助到你。

于 2013-01-29T13:43:54.047 回答
0

感谢大家的帮助,我终于设法得到一个工作 - 可双击 csv 文件,该文件分开打开并正确显示字母。对于那些对良好工作流程感兴趣的人,我们可以:

1.) 我的数据库完全使用 UTF8。2.) 我通过 php 将表单导出到我的数据库中。我正在使用 mysqli 并作为标题信息:

header("Content-Type: text/html; charset=ISO-8859");

我知道这会使数据库中的所有内容看起来都很糟糕,请随意使用 utf8 使其看起来正确,但在我的情况下并不重要。

3.) 我写了一个由 cron 守护进程执行的脚本,它 a) 删除了之前创建的 .csv 文件

rm -f path/to/csv ##I have 3 due to some renaming see below

b) 使用 mysql 创建新的 csv (这仍然是 UTF8)

mysql -hSERVERIP -uUSER -pPASS DBNAME -e "select * from DBTABLE;" > PATH/TO/output.csv

现在您有一个制表符分隔的 .csv 并且(如果您以 UTF8 格式从 PHP 导出)它将在 OpenOffice 等中正确显示,但在 Excel 中则不会。即使导入为 UTF8 也不起作用。

c) 使文件以分号分隔(Excel 标准,双击逗号分隔的文件将不起作用,至少不适用于欧洲版的 Excel)。我使用了一个小的 python 脚本 semicolon.py:

import sys
import csv

tabin = csv.reader(sys.stdin, dialect=csv.excel_tab)
commaout = csv.writer(sys.stdout, delimiter=";")
for row in tabin:
  commaout.writerow(row)

d) 现在我必须在我的 cron sh 文件中调用脚本:

/usr/bin/python PATH/TO/semicolon.py < output.csv > output_semi.csv

如果您将脚本用作 cron,请确保为每个文件使用完整路径。

e) 使用 iconv 将字符集从 UTF8 更改为 ISO-8859-1(Windows ANSI Excel 标准):

iconv -f utf8 -t ISO-8859-1 output_semi.csv > output_final.csv

就是这样。csv 在 Mac/Windows Excel 2010(已测试)上双击打开。

也许这对有类似问题的人有帮助。它把我逼疯了。

编辑:对于某些服务器,您不需要 iconv,因为数据库的输出已经是 ISO8859。您应该在执行 mysql 命令后检查您的 csv:

file output.csv

仅当字符集不是 iso8859-1 时才使用 iconv

于 2013-02-05T12:34:08.827 回答