我们之前使用了POI技术将回货表构造成excel文件输出并打印,但是我们依然遗留了许多的问题,这次我们将使用的POI的HSSF,升级为XSSF。
首先什么是HSSF、XSSF呢?其实它是根据不同的规格提供不同的功能。
结构:
HSSF - 提供读写Microsoft Excel格式档案的功能。
XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
HWPF - 提供读写Microsoft Word格式档案的功能。
HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
HDGF - 提供读写Microsoft Visio格式档案的功能。
我们之前提到过,早期微软Office系列,当时使用OLE2文档结构(纯2进制的文件,文件头都有规范的)。
微软在开发office2007版本时,做了一个重大的改革,重写了office。使用OOXML文档结构。现在excel文件实际上是一个XML格式文件。
POI支持OLE2格式文件,还支持OOXML,而且在OOXML格式文件时做了很大的优化。JXL只支持OLE2格式文件。
所以,我们使用XSSF会更大程度上的优化我们打印出来的excel文件,还有一个极其重要的一点,就是XSSF一次能够打印百万数据(具体1048576),而HSSF一次只能打印万行(65536)。
还有一些具体的优化比如:
1)升级对象
2)升级模板
3)升级写出的xlsx
我们接下来把原来Controller中的print方法修改一下,让它由HSSF改为XSSF:
仔细观察,我们只改了两个地方:
Workbook wb=new XSSFWorkbook();//打开一个模板文件,2007Excel以上版本
与
du.download(bs, response, "出货表.xlsx");
我们测试一下:
打开下载的文档
升级成功!很简单吧?
只不过XSSF比HSSF稍微慢了一点,因为要为百万级数据生成做准备,所以,一般我们选择POI的文件创建规则遵循以下原则:
实际工作中
HSSF 比较多,兼顾客户的环境
XSSF 应用比较少,当数据量比较大时,才采用
SXSSF 只用在海量数据的导出
首先什么是HSSF、XSSF呢?其实它是根据不同的规格提供不同的功能。
结构:
HSSF - 提供读写Microsoft Excel格式档案的功能。
XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
HWPF - 提供读写Microsoft Word格式档案的功能。
HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
HDGF - 提供读写Microsoft Visio格式档案的功能。
我们之前提到过,早期微软Office系列,当时使用OLE2文档结构(纯2进制的文件,文件头都有规范的)。
微软在开发office2007版本时,做了一个重大的改革,重写了office。使用OOXML文档结构。现在excel文件实际上是一个XML格式文件。
POI支持OLE2格式文件,还支持OOXML,而且在OOXML格式文件时做了很大的优化。JXL只支持OLE2格式文件。
所以,我们使用XSSF会更大程度上的优化我们打印出来的excel文件,还有一个极其重要的一点,就是XSSF一次能够打印百万数据(具体1048576),而HSSF一次只能打印万行(65536)。
还有一些具体的优化比如:
1)升级对象
2)升级模板
3)升级写出的xlsx
我们接下来把原来Controller中的print方法修改一下,让它由HSSF改为XSSF:
- //打印-XSSF
- @RequestMapping("/cargo/outproduct/print.action")
- public void print2(String inputDate,HttpServletResponse response) throws IOException{ //inputDate格式:yyyy-MM
- List<OutProductVO> dataList=outProductService.find(inputDate);
- /*System.out.println(dataList.size());
- System.out.println(inputDate);*/
- Workbook wb=new XSSFWorkbook();//打开一个模板文件,2007Excel以上版本
- Sheet sheet=wb.createSheet();
- Row nRow=null;
- Cell nCell=null;
- int rowNo=0; //行号
- int cellNo=1;//列号
- //声明样式对象和字体对象
- CellStyle nStyle=wb.createCellStyle();
- Font nFont=wb.createFont();
- //设置表格宽度
- sheet.setColumnWidth(0,1*300);//列宽
- sheet.setColumnWidth(1,26*300);//列宽
- sheet.setColumnWidth(2,12*300);//列宽
- sheet.setColumnWidth(3,29*300);//列宽
- sheet.setColumnWidth(4,10*300);//列宽
- sheet.setColumnWidth(5,12*300);//列宽
- sheet.setColumnWidth(6,8*300);//列宽
- sheet.setColumnWidth(7,10*300);//列宽
- sheet.setColumnWidth(8,10*300);//列宽
- sheet.setColumnWidth(9,8*300);//列宽
- //大标题,合并单元格
- sheet.addMergedRegion(new CellRangeAddress(0,0,1,9));//开会行,结束行,开始列,结束列
- //合并单元格的内容是写在合并前第一个单元格中
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(36);//行高
- nCell=nRow.createCell(1);
- nCell.setCellValue(inputDate.replaceFirst("-0","-").replaceFirst("-","年")+"月份出货表");//yyyy-MM
- nCell.setCellStyle(this.bigTitle(wb, nStyle, nFont));
- //配置标题行
- String [] title=new String[]{"客户","订单号","货号","数量","工厂","附件","工厂交期","船期","贸易条款"};
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(26.25f);//标题的高
- nStyle=wb.createCellStyle();//重新初始化样式
- nFont=wb.createFont();//重新初始化字体
- for (int i = 0; i < title.length; i++) {
- nCell=nRow.createCell(i+1);
- nCell.setCellValue(title[i]);
- nCell.setCellStyle(this.Title(wb, nStyle, nFont));
- }
- nStyle=wb.createCellStyle();//重新初始化样式
- nFont=wb.createFont();//重新初始化字体
- //处理数据
- for (int i = 0; i < dataList.size(); i++) {
- OutProductVO op=dataList.get(i);
- nRow=sheet.createRow(rowNo++);
- nRow.setHeightInPoints(24);//数据框的高
- cellNo=1;//列号初始化
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCustomName());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getcontractNo());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getProductNo());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getCnumber());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getFactoryName());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getExts());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getDelivery_preriod());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getShip_time());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- nCell=nRow.createCell(cellNo++);
- nCell.setCellValue(op.getTradeTerms());
- nCell.setCellStyle(this.Text(wb, nStyle, nFont));
- }
- /*OutputStream os=new FileOutputStream(new File("F:\\outproduct.xls"));
- wb.write(os);
- os.flush();
- os.close();*/
- //下载(使用了我们的工具类)
- DownloadUtil du=new DownloadUtil();
- ByteArrayOutputStream bs=new ByteArrayOutputStream();
- wb.write(bs);
- du.download(bs, response, "出货表.xlsx");
- }
仔细观察,我们只改了两个地方:
Workbook wb=new XSSFWorkbook();//打开一个模板文件,2007Excel以上版本
与
du.download(bs, response, "出货表.xlsx");
我们测试一下:
打开下载的文档
升级成功!很简单吧?
只不过XSSF比HSSF稍微慢了一点,因为要为百万级数据生成做准备,所以,一般我们选择POI的文件创建规则遵循以下原则:
实际工作中
HSSF 比较多,兼顾客户的环境
XSSF 应用比较少,当数据量比较大时,才采用
SXSSF 只用在海量数据的导出