在POI中提供了Excel文件的两种实现类,HSSFWrorBook和XSSFWorkBook,前者适用于Excel文件的老版本,后缀名为“.xls”,而后者适用于后缀名为“.xlsx”。
解析excel
创建WookBook类的实例化对象
创建一个WookBook类的实例化对象,与此同时创建输入流对文件进行文件的读取,按照文件的结构逐层读取。
//方式1
try (Workbook workbook = new XSSFWorkbook();
FileInputStream in = new FileInputStream("D:\\test\\1627356552686.xlsx")) {
} catch (IOException e) {
e.printStackTrace();
}
try (//方式2 通过匿名子类
Workbook workbook1 = new XSSFWorkbook(new FileInputStream("D:\\test\\1627356552686.xlsx"))) {
} catch (IOException e) {
e.printStackTrace();
}
获取工作簿
//根据名称获取
Sheet sheet = workbook.getSheet("yyyy");
//根据下标获取第一个工作簿
Sheet sheet = workbook.getSheetAt(0);
获取当前工作簿中的数据行
//遍历所有行
for(Row row : sheet) {
System.out.println(row);
}
//遍历部分行
// sheet.getLastRowNum():总行数
for (int i = 0; i < sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
System.out.println(row);
}
获取当前行的每个单元格
Cell cell = row.getCell(0); //得到第一个单元格
cell.getNumericCellValue() //得到第一个单元格的内容
// 也可以使用foreach进行单元格的遍历
for(Cell cell : row) {
}
写入excel
创建WookBook类的实例化对象
同前述
创建工作簿
Sheet sheet1 = workbook.createSheet();
//也可以自定义工作簿名称
Sheet sheet2 = workbook.createSheet("y");
创建数据行
Row row = sheet.createRow(0); //创建当前工作簿的第一行
创建单元格并且写入内容
Cell cell = row.createCell(0); //创建第一个单元格
//设置当前单元格的内容
cell.setCellValue(UUID.randomUUID().toString());
设置单元格格式
// 创建单元格样式
DataFormat dataFormat = workbook.createDataFormat();
Short formatCode = dataFormat.getFormat("yyyy-MM-dd HH:mm:ss");
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(formatCode);
// 为当前行创建单元格
Cell cell1 = row.createCell(1);
cell1.setCellStyle(cellStyle); // 设置单元格样式
cell1.setCellValue(new Date()); // 保存当前日期时间至本单元格
//设置单元格的水平对齐类型。 此时水平居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);
// 设置单元格的垂直对齐类型。 此时垂直靠底边
cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);
写入excel文件
使用的是WorkBook对象的write!
workbook.write(out);
写入范例
public static void downloadImportTemplate() throws Exception {
String fileName = “xx”
File fileTemplate = new File(fileName);
FileInputStream is = new FileInputStream(fileTemplate);
XSSFWorkbook workbook = new XSSFWorkbook(is);
XSSFSheet sheet = workbook.getSheetAt(0);// 获取第1个工作簿
XSSFRow row0 = sheet.createRow(0);// 创建第1行
XSSFFont cellFont = workbook.createFont();// 创建样式
cellFont.setFamily(FontFamily.DECORATIVE);
XSSFDataFormat df = workbook.createDataFormat();
cellFont.setColor((short)32767);
XSSFCellStyle teamCellStyle = workbook.createCellStyle();
teamCellStyle.setAlignment(HorizontalAlignment.CENTER);
teamCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
teamCellStyle.setDataFormat(df.getFormat("@"));
teamCellStyle.setFillForegroundColor(new XSSFColor(new Color(236, 238, 238)));
teamCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
teamCellStyle.setBorderTop(BorderStyle.THIN);
teamCellStyle.setBorderBottom(BorderStyle.THIN);
teamCellStyle.setBorderRight(BorderStyle.THIN);
XSSFCell cell = row0.createCell(0);// 创建第1行的第1列
cell.setCellStyle(teamCellStyle);// 为单元格设置样式
cell.setCellValue(new XSSFRichTextString("aa"));// 设置第1行第1列的内容
// 后面每1行每1列都像前3行那样写,此处不再赘述
workbook.write(out);// excel写入workbook
out.flush();
out.close();
return null;
}
问题
在开发过程中,Workbook workbook1 = new XSSFWorkbook(new FileInputStream("D:\\test\\1627356552686.xlsx"))
报错:
org.apache.poi.poifs.filesystem.OfficeXmlFileException: 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)
这是由于 excel 版本问题,我们使用了解析 2003版excel (.xls)的方法来解析 2007版的 excel (.xlsx)后抛出的异常。既然解析需要根据 excel版本 而使用不同的 对象,那我们直接根据文件后缀做个判断就好,例如:
//获得原始文件名
String oriName = myfile.getOriginalFilename();
if (oriName.endsWith("xls")) {
//使用 HSSFWorkbook 解析
} else {
//使用 XSSFWorkbook 解析
}
WorkbookFactory.create() 函数中的源码如下:
/**
* Creates the appropriate HSSFWorkbook / XSSFWorkbook from
* the given InputStream.
* Your input stream MUST either support mark/reset, or
* be wrapped as a {@link PushbackInputStream}!
*/
public static Workbook create(InputStream inp) throws IOException, InvalidFormatException {
// If clearly doesn't do mark/reset, wrap up
if(! inp.markSupported()) {
inp = new PushbackInputStream(inp, 8);
}
if(POIFSFileSystem.hasPOIFSHeader(inp)) {
return new HSSFWorkbook(inp);
}
if(POIXMLDocument.hasOOXMLHeader(inp)) {
return new XSSFWorkbook(OPCPackage.open(inp));
}
throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
}
因为HSSFWorkbook和XSSFWorkbook都实现了Workbook接口,WorkbookFactory.create()
函数里面,对当前传入的excel文件流进行了版本判断,并根据不同的版本,返回不同的Workbook对象。所以可以使用poi-ooxml中的WorkbookFactory.create(inputStream)
来创建Workbook。