首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PHP中处理xls文件的不同编码?

如何在PHP中处理xls文件的不同编码?
EN

Stack Overflow用户
提问于 2011-03-21 19:44:48
回答 3查看 3.2K关注 0票数 1

我正在开发一个涉及从xls文件解析数据的php脚本。我使用的是库phpexcelreader。所有这些都是有效的,但我偶然发现了一个奇怪的问题。某些文件的解析不正确。看起来xls文件可能在内部使用不同的字符编码。至少,然后我通过iconv -f cp1251 -t utf8通过管道从我的脚本输出,字符串得到更正。

Phpexcelreader有一个指定输出编码的选项,但看起来它缺乏检测输入编码的能力。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-03-21 20:16:06

工作簿对象的_defaultEncoding属性可以设置为包含Excel文件使用的字符集,然后阅读器使用该属性处理到UTF-16LE的转换,但它不会识别内部字符集本身。

如果您定义

代码语言:javascript
复制
define('SPREADSHEET_EXCEL_READER_TYPE_CODEPAGE',  0x0042);

在其他SPREADSHEET_EXCEL_READER_TYPE定义中,然后修改从第464行开始的切换语句,以包括SPREADSHEET_EXCEL_READER_TYPE_CODEPAGE的用例。这种情况的逻辑需要是这样的:

代码语言:javascript
复制
$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方法(在某些时候似乎已经从代码中剥离出来),如下所示

代码语言:javascript
复制
function _GetInt2d($data, $pos)
{
    return ord($data[$pos]) | (ord($data[$pos + 1]) << 8);
}

并创建一个_CodePageNumberToName方法以从其数值返回代码页名称:

代码语言:javascript
复制
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阅读器

票数 2
EN

Stack Overflow用户

发布于 2011-04-06 18:10:23

我的2点看法:

我刚刚用这个替换了encodeUTF16

代码语言:javascript
复制
 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行

代码语言:javascript
复制
$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

票数 0
EN

Stack Overflow用户

发布于 2018-04-19 15:39:58

对于波斯语,我在第568行或其他版本336之后添加了一行。

代码语言:javascript
复制
$retstr = ($asciiEncoding) ? $retstr : $this->_encodeUTF16($retstr);

$retstr=iconv("UTF-16LE","UTF-8", $retstr);

这段代码支持波斯语,但是你不能再使用英语了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5377146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档