起因
最近在做一个Excel导出的功能,要将数据库中的数据到处到excel中。众所周知,现在的Excel已经不是微软Office一家独大的时候了,Apple的Numbers和WPS在各自的平台上也有着很大一部分占有率,所以这次的要求也是需要兼容这3个主流的App。
本以为3个应用对xls的处理方式都是按照统一标准的,没想到却出现了WPS下可以正常打开,但是Excel下却无法正常打开的问题。Excel报的错误也是一样的微软风格“未知错误”,对排查问题根本没帮助。
排查过程
起初,我觉得问题应该和内容无关,而是跟头部的信息有关系。推断依据:我当时三观里面认为xls是一个类似txt之类的文本格式,不会涉及到由html带来的问题。但是,我在对比完另外一个可以正常导出文件的功能后,发现在头部信息完全一样(只有名字不一样)的时候,也是一个正常一个不正常,于是我开始怀疑最初的想法,我觉得问题应该是和内容有关系。
后来,我对比了一下2份导出的文件,一份里面只有数字(金额),而另外一份里面则包含用户的信息(公司名、账号等等)。我认为可能是一些奇葩的公司名字(带有特殊标点)导致的问题。于是,我把所有公司名字都用base64_encode函数转换了一下,发现真的可以导出了。从此,我确定问题应该是出在内容上。
最后,我发现xls也可以根据html和css来组织文本样式,我理所当然的推断,Excel可能采用了某种浏览器内核(也可能是变种)来处理了xls文件,那么xss(比方<script>alert(111);</script>)可能会破坏渲染过程,从而报错。所以,我尝试了在页面上做xss过滤的函数htmlspecialchars来过滤数据。终于得到了想要的结果,这次的问题排查也就此结束。
结论
xls文件的渲染也与html和css相关,所以为了保证文件能够被正常渲染,不要在输出的数据中直接带有xss内容,如果有,可以用过滤函数进行过滤后展示。
注
在htmlspecialchars过滤后,“<”会变成“&l t;(没空格)”,其它标点同理。