您的位置:首页 >> Web开发 >> CGI技术 >> 正文
CGI技术 RSS
 

用Perl来分析并生成中文Excel文件

http://www.rdxx.com 07年10月01日 00:00 我要投稿

关键词: 中文 , 生成 , Excel文件 , Perl , 文件 , Excel
 


  # Check for a valid 2-byte char string.
croak "Uneven number of bytes in Unicode string" if $num_bytes % 2;

# Change from UTF16 big-endian to little endian
$str = pack "v*", unpack "n*", $str

那么也就是说将这段代码加入到add_worksheet()适当的位置就可以喽?答案是令人沮丧的。为了查找原因再次回到Spreadsheet::ParseExcel.pm,从调入Excel文件分析Excel文件开始,看看工作簿名称是如何得到的。

分析代码发现,TextFmt()处理工作簿名称时是这样的:$sWsName = $oBook->{FmtClass}->TextFmt($sWsName, 'ucs2')。TextFmt()函数还有一部分是针对Excel文件个别类型的字符串(如header,footer,工作簿名称等)不做上面提到的处理(s/(.)/\x00$1/sg)。可是这个不是关键问题,不能解释为什么直接装换为unicode的字符不能写入。

进一步分析发现,相对于单元格的字符其他的特殊的字符再进行TextFmt()格式化之前都有进行类似_SwapForUnicode(\$sWsName)的调用,也就是说还有特殊处理:

sub _SwapForUnicode(\$)
{
my($sObj) = @_;
#for(my $i = 0; $i for(my $i = 0; $i<(int (length($$sObj) / 2) * 2); $i+=2) {
my $sIt = substr($$sObj, $i, 1)
substr($$sObj, $i, 1) = substr($$sObj, $i+1, 1);
substr($$sObj, $i+1, 1) = $sIt
}
}

根据以上所有的分析,最后得出了一个解决方案:

my $sWsName = $Map->to_unicode($sWsName);
&SwapForUnicode(\$name);
my $worksheet = $workbook->add_worksheet($name, 1);

再经历两天的失败了以后,成功意外的降临了,上面的代码是可行的。第一行,将非Unicode的字符转换为Unicode的;第二行,变更其存储格式使之符合Excel文件的要求;第三行,通过带参数$encoding的调用,执行了相当于write_unicode()中写入unicode字符的代码(事实上这部分代码所说的自行添加的部分,NOTE:修改了Module的源文件):$name = pack "v*", unpack "n*", $name;

最后是与标题无关的总结。

Spreadsheet这两个模块处理Excel的能力太过独立,二者很难结合的很好。两个模块要么只能读,要么只能写,必须要一个中间的数据存储。

虽然说ParseExcel使用WriteExcel模块写了一个SaveParser,可本质上还是通过用SaveAS方法来新建了一个Excel对象并把数据复制过去,并没有真正意义上的“Save”。

而且SaveParser还有一个严重的问题:它内部同时使用了ParseExcel和WriteExcel的Workbook对象,可是却无法将二者统一起来:两个对象执行同一功能的函数名不同,如AddFormat()和add_format(),让人很难确定什么时候改用什么;甚至很多功能函数没有继承下来,如keep_leading_zeros(),这给我写“000946”带来了很大的麻烦。

希望以后能够出一个Module将这二者很好的结合起来新Module。

上一页 下一页


 
 
标签: 中文 , 生成 , Excel文件 , Perl , 文件 , Excel 打印本文
 
 
  热点搜索
 
 
 



Valid XHTML 1.0 Transitional
Copyright ©2005 - 2008 Rdxx.Com,All Rights Reserved
收藏本页
收藏本站