我正在开发一个涉及从xls文件解析数据的php脚本。我使用的是库phpexcelreader。所有这些都是有效的,但我偶然发现了一个奇怪的问题。某些文件的解析不正确。看起来xls文件可能在内部使用不同的字符编码。至少,然后我通过iconv -f cp1251 -t utf8通过管道从我的脚本输出,字符串得到更正。
Phpexcelreader有一个指定输出编码的选项,但看起来它缺乏检测输入编码的能力。有什么想法吗?
发布于 2011-03-21 20:16:06
工作簿对象的_defaultEncoding属性可以设置为包含Excel文件使用的字符集,然后阅读器使用该属性处理到UTF-16LE的转换,但它不会识别内部字符集本身。
如果您定义
define('SPREADSHEET_EXCEL_READER_TYPE_CODEPAGE', 0x0042);在其他SPREADSHEET_EXCEL_READER_TYPE定义中,然后修改从第464行开始的切换语句,以包括SPREADSHEET_EXCEL_READER_TYPE_CODEPAGE的用例。这种情况的逻辑需要是这样的:
$length = $this->_GetInt2d($this->_data, $pos + 2);
$recordData = substr($this->_data, $pos + 4, $length);
// move stream pointer to next record
$pos += 4 + $length;
// offset: 0; size: 2; code page identifier
$codepage = $this->_GetInt2d($recordData, 0);
$codepage = $this->_CodePageNumberToName($codepage)重新创建_GetInt2d方法(在某些时候似乎已经从代码中剥离出来),如下所示
function _GetInt2d($data, $pos)
{
return ord($data[$pos]) | (ord($data[$pos + 1]) << 8);
}并创建一个_CodePageNumberToName方法以从其数值返回代码页名称:
function _CodePageNumberToName($codePage = '1252')
{
switch ($codePage) {
case 367: return 'ASCII'; break; // ASCII
case 437: return 'CP437'; break; // OEM US
case 720: throw new Exception('Code page 720 not supported.');
break; // OEM Arabic
case 737: return 'CP737'; break; // OEM Greek
case 775: return 'CP775'; break; // OEM Baltic
case 850: return 'CP850'; break; // OEM Latin I
case 852: return 'CP852'; break; // OEM Latin II (Central European)
case 855: return 'CP855'; break; // OEM Cyrillic
case 857: return 'CP857'; break; // OEM Turkish
case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro
case 860: return 'CP860'; break; // OEM Portugese
case 861: return 'CP861'; break; // OEM Icelandic
case 862: return 'CP862'; break; // OEM Hebrew
case 863: return 'CP863'; break; // OEM Canadian (French)
case 864: return 'CP864'; break; // OEM Arabic
case 865: return 'CP865'; break; // OEM Nordic
case 866: return 'CP866'; break; // OEM Cyrillic (Russian)
case 869: return 'CP869'; break; // OEM Greek (Modern)
case 874: return 'CP874'; break; // ANSI Thai
case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS
case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK
case 949: return 'CP949'; break; // ANSI Korean (Wansung)
case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5
case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8)
case 1250: return 'CP1250'; break; // ANSI Latin II (Central European)
case 1251: return 'CP1251'; break; // ANSI Cyrillic
case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program
case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7)
case 1253: return 'CP1253'; break; // ANSI Greek
case 1254: return 'CP1254'; break; // ANSI Turkish
case 1255: return 'CP1255'; break; // ANSI Hebrew
case 1256: return 'CP1256'; break; // ANSI Arabic
case 1257: return 'CP1257'; break; // ANSI Baltic
case 1258: return 'CP1258'; break; // ANSI Vietnamese
case 1361: return 'CP1361'; break; // ANSI Korean (Johab)
case 10000: return 'MAC'; break; // Apple Roman
case 32768: return 'MAC'; break; // Apple Roman
case 32769: throw new Exception('Code page 32769 not supported.');
break; // ANSI Latin I (BIFF2-BIFF3)
case 65001: return 'UTF-8'; break; // Unicode (UTF-8)
}
}并将返回值存储在$_defaultEncoding中
或者,首先切换到可以正确处理代码页的Excel阅读器
发布于 2011-04-06 18:10:23
我的2点看法:
我刚刚用这个替换了encodeUTF16
function _encodeUTF16($string, $check = false) {
if ($check) {
$from = api_detect_encoding($string);
$string = api_convert_encoding($string, $this->_defaultEncoding, $from);
return $string;
}
$string = api_convert_encoding($string, $this->_defaultEncoding, 'UTF-16LE');
return $string;并更改568行
$retstr = ($asciiEncoding) ? $this->_encodeUTF16($retstr, true) : $this->_encodeUTF16($retstr);这些函数api_detect_encoding和api_convert_encoding可以在这个库中找到:
http://code.google.com/p/chamilo/source/browse/main/inc/lib/internationalization.lib.php?repo=classic
发布于 2018-04-19 15:39:58
对于波斯语,我在第568行或其他版本336之后添加了一行。
$retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr);
$retstr=iconv("UTF-16LE","UTF-8", $retstr);这段代码支持波斯语,但是你不能再使用英语了。
https://stackoverflow.com/questions/5377146
复制相似问题