我们使用POI中的HSSFWorkbook来读取Excel数据。 + v! g7 K5 t" u2 rpublic void test(File file) throws IOException { * n% z7 e: e1 c; Y4 B InputStream inp = new FileInputStream(file);/ j" F1 i' y( v+ K" Q
HSSFWorkbook workbook = new HSSFWorkbook(inp); * N5 n8 g/ g$ e x" R& y9 w8 k7 { ) X8 @' B" U6 V- i
// workbook...遍历操作# M) g6 C; a- c2 n# u
}* \& P/ h4 Z* U; g5 M/ l( w
% h6 Q1 I v7 y L上边代码,读取Excel2003(xls)的文件没问题,但是一旦读取的是Excel2007(xlsx)的文件,就会报异常:“The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)” % j. T' r% V' A& M* L查阅了资料,Excel2007版本的Excel文件需要使用XSSFWorkbook来读取,如下:5 z# o5 r0 I0 m, b/ S
public void test(File file) throws IOException {+ g. Z/ B+ u9 B" |
InputStream inp = new FileInputStream(file);, S2 z8 F' u3 N0 X3 Y9 b$ U
XSSFWorkbook workbook = new XSSFWorkbook(inp);% j- t6 R6 T' Q& R8 [# Y
( K9 e5 D9 Q' E/ E2 `: h- Z/ ~6 H
// workbook...遍历操作& K3 M5 _" p1 C' A( D
}/ c4 P e9 @3 r. v
注意:XSSFWorkbook需要额外导入poi-ooxml-3.9-sources.jar和poi-ooxml-schemas-3.9.jar。7 l2 Y+ }5 \+ o6 a
这样,Excel2007的导入没问题了,但是导入Excel2003又报异常。 : r: f, C; E) \- e所以,在导入Excel的时候,尽量能判断导入Excel的版本,调用不同的方法。 0 H; e- k% t% J% ?1 y0 R我想到过使用文件后缀名来判断类型,但是如果有人将xlsx的后缀改为xls时,如果使用xlsx的函数来读取,结果是报错;虽然后缀名对了,但是文件内容编码等都不对。 6 c! B0 k" X1 ~6 ]0 T i; R( B; H最后,推荐使用poi-ooxml中的WorkbookFactory.create(inputStream)来创建Workbook,因为HSSFWorkbook和XSSFWorkbook都实现了Workbook接口。代码如下: : r+ p+ Y+ D) sWorkbook wb = WorkbookFactory.create(is);6 n9 Q) M: ]9 t; y, g) j
/ Z# q0 T7 t/ I6 C( l% N
可想而知,在WorkbookFactory.create()函数中,肯定有做过对文件类型的判断,一起来看一下源码是如何判断的: & h* O# `: p4 i/**/ K: _3 n# S' x3 M$ d, o8 s
* Creates the appropriate HSSFWorkbook / XSSFWorkbook from$ j, t- k# l$ W. ?7 e6 D3 n$ K
* the given InputStream. % ?% \ q/ O0 M6 S, p * Your input stream MUST either support mark/reset, or - W+ n0 P3 y3 |4 f! l. V * be wrapped as a {@link PushbackInputStream}! , ~% v. H6 P. e4 j; ~6 ? */ + ]( f" V5 H0 H$ n, z public static Workbook create(InputStream inp) throws IOException, InvalidFormatException { ' b9 B2 h. ?6 b // If clearly doesn't do mark/reset, wrap up }& R. K' |* F; I0 b
if(! inp.markSupported()) {! e1 q3 m* a, g4 n/ k) y, ?. }
inp = new PushbackInputStream(inp, 8);5 i+ k* P1 P% j4 M' Z# u o1 h" P
}# s/ u( B. z0 _, ^; A: N) u
$ P, e0 ?. p" n8 r' w3 J) G M; j if(POIFSFileSystem.hasPOIFSHeader(inp)) {3 f7 q3 q8 Z0 g8 C7 ?0 M8 E6 A
return new HSSFWorkbook(inp); ' a2 }3 [0 s1 Q# Y }. S& r2 E s' H, m
if(POIXMLDocument.hasOOXMLHeader(inp)) { ) ]; N0 x; Y$ V. S return new XSSFWorkbook(OPCPackage.open(inp)); - I. y: P- t$ Z6 ] }+ t- t! ?- c! G, X1 b
throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");) h9 [8 D8 n( |& P8 I
}# P" }* A8 x. D1 K