jxl读取excel的一个搞脑子的问题

jxl读取excel的一个搞脑子的问题

问题描述:

前几天被叫去看一个老系统,做好大概几个月了。



说是excel导入出了问题,有一批数据就是不能导入。而且也是excel格式的,看不出问题。



然后我过去本机跑了一下,报的不是业务异常,是jxl读文件的异常,如下:



jxl.read.biff.BiffException: Unable to recognize OLE stream
at jxl.read.biff.CompoundFile.<init>(CompoundFile.java:116)
at jxl.read.biff.File.<init>(File.java:127)
at jxl.Workbook.getWorkbook(Workbook.java:221)
at jxl.Workbook.getWorkbook(Workbook.java:198)




然后去查了下jxl的源代码,这里抛出的异常。

for (int i = 0; i < IDENTIFIER.length; i++)
{
if (data[i] != IDENTIFIER[i])
{
throw new BiffException(BiffException.unrecognizedOLEFile);
}
}




说明咱导入的这个excel不是jxl认定的标准OLE file,真是见鬼了。。打开也好好的是excel。怎么就不是标准的OLE file?



接着查这批不能导入的excel到底有什么问题,查来查去后来无意中用ultraEdit打开了一下,结果发现居然不是2进制文件,而是一个网页文件。马上打开另外一个可以导入的xls文件,发现直接出来的是2进制。继续打开前一个不能导入的excel文件仔细查看,结果在选择另存为的时候跳出来是这个样子:



原来发现本质是个网页文件。。



然后再尝试不加引号保存,发现保存完图标也变了。文件名变成demo.xls.htm  这下基本确定这批excel文件其实都是网页文件,解决办法我就是先让客户全部另存一下,选择ms excel工作簿保存再导入。



然后客户需求来了,问我为啥要另存一下,不是数据都在的么?



查了半天资料,解决不掉这个囧问题。 总结了下面几点:



1.加引号“demo.xls” 和不加引号保存成网页文件为什么结果不同?如果加了引号但是不加".xls"的话还是保存为网页格式,并不会批个xls的外壳。



2.jxl没有能力辨别这样的xls文件。。只能抛BiffException。。以后各位兄弟操作excel的时候如果抛了BiffException异常,各位可以看下是不是这个原因。。



3.有兄弟遇见过这个囧问题么?有啥解决办法么? 去客户那里了解了一下,他们这些excel是让另外一个公司做的,在网页上自动生成下载的,以后让他们一个一个另存估计要骂娘。




问题补充
要说容错性的话,除了上面碰到的这个情况。其他的抛不能读取的情况我貌似还没见到过。

如果上面的类型转换不能通过java来解决的话,只有让用户自己去另存这个唯一的办法了?sigh。。。



问题补充:
我囧。。。



半年前的东西怎么出现到这里来了。。



最后我是用Lucas Lee的做法解决的,先判断是不是OLE格式,然后如果是的话就走jxl路线,如果不是 就当处理html一样按文本方式读入解决。。很累人。。

除了让用户另存为xls格式外,比较主动的做法还有:识别html格式的数据,并导入。

JXL得容错性超烂, 有时候格式不对也会出错。

下载的时候要设置http head力的类型是excel.

刚碰到,让用户save as...

昨天试了下jxl,刚好也碰到这个问题,当时是新建了另外一个excel了事,没有去追根问底,多谢楼主

困扰已久,期待各位高手解决!

[quote="h521999"]困扰已久,期待各位高手解决![/quote]
很多网站导出excel都用html或是xhtml。
根本不是BIFF的格式,jxl和poi当然用不了。
vba之类的功能也用不了。

没办法。

[quote="h521999"]困扰已久,期待各位高手解决![/quote]
有条件的还是推荐使用exreport之类的基于dsoframer的
纯excel的导出功能。

汗,我明白了,我以前也老出错,jxl生成的xls ,有一个网页控件怎么也不能识别,但是生成的xls却可以用excel打开!

用poi纯excel的导出

一般在下载的时候都会默认头为text/html,这样会导致你下载的文件格式发生变化,所以,你可以如下设置
public String getContentType(String suffix) {
String contentType = null;
if (suffix.equals(".avi")) {
contentType = "video/avi";
} else if (suffix.equals(".bmp")) {
contentType = "application/x-bmp";
} else if (suffix.equals(".doc")) {
contentType = "application/msword";
} else if (suffix.equals(".gif")) {
contentType = "image/gif";
} else if (suffix.equals(".htm") || suffix.equals(".html")) {
contentType = "text/html";
} else if (suffix.equals(".jpg") || suffix.equals(".jpeg")) {
contentType = "image/jpeg";
} else if (suffix.equals(".mht") || suffix.equals(".mhtml")) {
contentType = "message/rfc822";
} else if (suffix.equals(".mp3")) {
contentType = "audio/mp3";
} else if (suffix.equals(".ppt")) {

contentType = "application/vnd.ms-powerpoint";
} else if (suffix.equals(".pptx")) {
contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
} else if (suffix.equals(".rm")) {
contentType = "application/vnd.rn-realmedia";
} else if (suffix.equals(".rmvb")) {
contentType = "application/vnd.rn-realmedia-vbr";
} else if (suffix.equals(".xls")) {
contentType = "application/x-xls";
} else if (suffix.equals(".xml")) {
contentType = "text/xml";
} else if (suffix.equals(".rar")) {
contentType = "application/octet-stream";
} else if (suffix.equals(".zip")) {
contentType = "application/x-zip-compressed";
} else if (suffix.equals(".swf")) {
contentType = "application/x-shockwave-flash";
} else if (suffix.equals(".wav")) {

contentType = "audio/wav";
} else if (suffix.equals(".txt")) {
contentType = "text/plain";
}
return contentType;
}

[size=x-large][color=red]
下载方法[/color][/size]
public void downLoad(String filePath, String contentType) throws Exception {

File f = new File(filePath);
if (!f.exists()) {
res.sendError(404, "对不起,下载文件没有找到,无法下载!");
return;
}
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[1024];
int len = 0;
res.reset();
[size=x-large][color=red]// 非常重要,设置下载文件的格式[/color][/size]
res.setContentType(contentType + ";charset=utf-8");
res.setHeader("Content-Disposition", "attachment; filename="

  • f.getName()); OutputStream out = res.getOutputStream(); while ((len = br.read(buf)) > 0) out.write(buf, 0, len); br.close(); out.flush(); out.close(); }