一次Mono解析Excel文档编码出错排查记录

 最近在捯饬Asp.Net站点部署到Linux平台上面,在文档导入的操作中经过网上搜索采用了能够支持跨平台的ExcelDataReader组建。在本地windows上测试通过NuGet安装的组建,这货依赖了SharpZipLib .Net下鼎鼎有名的解压缩组建,应该用来解压Excel文档的。本地测试没读取正常没有问题,但发布到Linux上运行总是无法读取,返回Null,这让我很是迷惑!接下来准备找出问题所在~

   1)下载了ExcelDataReader源码本地编译测试 问题依然存在,读取不到数据。

   2)Linux平台非开发环境,在源码上定位到错误打印方法上发现输出是ExceptionMessage,更改为.ToString() 并用控制台打印输出,观察代码出错行。得到如下结果:

错误信息居然是SharpZipLib报的...... 好吧,继续下载SharpZipLib源码找问题。

    3)下载完成SharpZipLib源码,定位到SharpZipLib.Zip.ZipConstants.ConvertToString (System.Byte[] data, Int32 count)方法:

这里代码很简单,错误是找不到对象,if判断就是检查data是否为null的,那么肯定不是判断里面的错误了。那么只有可能是下面的字节数组转字符串报错的,仔细看下不明白int类型的DefaultCodePage是什么鬼,和我平时写的Encoding.GetEncoding("utf8").GetString(data, 0, count);不一样。遂去找了下DefaultCodePage的定义:

找了下CodePage的定义,原来这玩意叫做内码表 是定义了字符编码类型映射的一个整形数字

百度百科这样说:

1 CodePage:可读/可写。整型。定义用于在浏览器中显示页内容的代码页。代码页是字符集的数字值,不同的语言使用不同的代码页。例 如,ANSI代码页为1252,日文代码页为932,简体中文代码页为936。一般情况下,当你上传到国外网页空间,或者提取数据库记录等出现乱码时,就 采用这种方法解决。

嗯,简体中文是936,难道我的文档是中文的原因?可是我也改成英文单词还是不行啊,试着打印下运行中的这个DefaultCodePage是多少:

OEMCodePage又是什么鬼呢?

找到这个介绍:http://dcx.sap.com/1200/zh/dbadmin/win-collation-natlang.html 意思是说这是老的Dos环境中使用的编码,我还以为服务器设备制造商所在地区的编码呢。。。。

(⊙ˍ⊙) 没错的样子,编码对的。。。

不解,先把这玩意改掉再说  

return Encoding.GetEncoding(Encoding.Default.CodePage).GetString(data, 0, count);

  

我也用CodePage,用.Net环境获取到的CodePage,然后运行测试,没问题了:

文档内容:

解析代码:

FileStream stream = System.IO.File.Open("ArticleTemplate.xlsx", FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
Console.WriteLine("");
excelReader.IsFirstRowAsColumnNames = true;
DataSet ds = excelReader.AsDataSet();
if (ds == null)
{
    Console.WriteLine("ds Is Null");
}
else
{
    Console.WriteLine("Read Ok");
}
foreach (DataTable dt in ds.Tables)
{
    foreach (DataRow dr in dt.Rows)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            Console.WriteLine(dr[i]);
        }
    }
}

  

(。_。)好吧,居然是这个问题导致的,那么.net环境在mono上获取的CodePage是多少呢?

查询得到 65001 代表的是 UTF-8

那么我的win环境下是什么样子呢?

都是936 也就是简体中文 也就是GBK编码。

现在的情况是linux环境获取到GBK编码但不能用,难道我的Linux环境没有GBK编码?locale查看当前系统使用的编码:

清一色的UTF8 没有GBK。 locale -a命令可以查看支持的编码,有显示支持GBK。

那么只能猜测 mono上运行.Net 程序做编码转换的时候只能转换成当前使用的编码?

目前更改成Encoding.Default能解决编码出错的问题了,但实际原因是不是我猜测的这样,我也不知道了。。。

posted @ 2015-08-10 18:12  yesicoo  阅读(677)  评论(0编辑  收藏  举报