这次是参与一个老项目的维护工作,在测试的过程中发现有一个遗留的bug,数据导出时,当列超过256时,则超出的数据无法正常导出显示。查了一些资料才知道原来项目中使用的jxl
本身有这个问题,需要更换成POI
才能真正解决.
首先添加项目依赖,由于项目是老项目,依赖的jar包都没有拿最新的
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans --> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>2.4.0</version> </dependency>
这里还需要注意一个问题,就是xmlbeans的版本不能使用2.3.x及以前的,否则会报错,更新到2.4.0即可解决。
使用POI
导出数据可以使用有三个组件
HSSFWorkbook
是操作Excel 2003及以前的版本,扩展名是*.xls
XSSFWorkbook
是操作Excel 2007后的版本,扩展名是*.xlsx
SXSSFWorkbook
从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式。对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。
我这里使用 SXSSFWorkbook
写了一个例子
import java.awt.Color; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFColor; public class Xml2ExcelUtil { public static void xmlToExcel(String title, String[] headerArray, List<String[]> dataList) { FileOutputStream out = null; try { SXSSFWorkbook workbook = new SXSSFWorkbook(); SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet(title); //设置默认单元格长度,表示12个字符的长度,这里需要先设置Column再设置Row才能生效 //如果在数据填充时使用sheet.setColumnWidth(columnIndex, width)循环设置单元格长度的话非常耗时,不建议使用 sheet.setDefaultColumnWidth(12); //设置默认行高,表示2个字符的高度 sheet.setDefaultRowHeight((short) (2 * 256)); // 产生表格标题行,下标是从0开始 Row row = sheet.createRow(0); Cell cellTiltle = row.createCell(0); // sheet样式定义【getColumnTopStyle()/getStyle()均为自定义方法 - 在下面 - 可扩展】 CellStyle style = getStyle(workbook); // 单元格样式对象 //插入表格标题,并合并 sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headerArray.length)); cellTiltle.setCellStyle(style); cellTiltle.setCellValue(title); int titleRows = 1;//标题栏所占行数 Row row2 = sheet.createRow(titleRows);//表格标题所在行 for (int i = 0; i < headerArray.length; i++) { String text = headerArray[i]; Cell cellName = row2.createCell(i); cellName.setCellType(SXSSFCell.CELL_TYPE_STRING); // 设置列头单元格的数据类型 cellName.setCellValue(text); // 设置列头单元格的值 cellName.setCellStyle(style); // 设置列头单元格样式 } for (int i = 0; i < dataList.size(); i++) { String[] datas = dataList.get(i); Row dataRow = sheet.createRow(titleRows + 1 + i);// 标题栏所占行数+表格标题所占行数+当前第几行 for (int j = 0; j < datas.length; j++) { String text = datas[j]; Cell cellName = dataRow.createCell(j); cellName.setCellType(SXSSFCell.CELL_TYPE_STRING); // 设置单元格的数据类型 cellName.setCellValue(text); // 设置单元格的值 cellName.setCellStyle(style); // 设置单元格样式 } } String filePath = "C:\\test\\"; String fileName = "test-" + System.currentTimeMillis() + ".xlsx"; out = new FileOutputStream(filePath+fileName); workbook.write(out); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* * 设置单元格样式 */ public static CellStyle getStyle(SXSSFWorkbook workbook) { // 设置字体 Font font = workbook.createFont(); // 设置字体大小 font.setFontHeightInPoints((short) 10); // 字体加粗 // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 设置字体名字 font.setFontName("Courier New"); // 设置样式; CellStyle style = workbook.createCellStyle(); // 设置底边框; style.setBorderBottom(CellStyle.BORDER_THIN); // 设置底边框颜色; style.setBottomBorderColor(new XSSFColor(new Color(0, 0, 0)).getIndexed()); // 设置左边框; style.setBorderLeft(CellStyle.BORDER_THIN); // 设置左边框颜色; style.setLeftBorderColor(new XSSFColor(new Color(0, 0, 0)).getIndexed()); // 设置右边框; style.setBorderRight(CellStyle.BORDER_THIN); // 设置右边框颜色; style.setRightBorderColor(new XSSFColor(new Color(0, 0, 0)).getIndexed()); // 设置顶边框; style.setBorderTop(CellStyle.BORDER_THIN); // 设置顶边框颜色; style.setTopBorderColor(new XSSFColor(new Color(0, 0, 0)).getIndexed()); // 在样式用应用设置的字体; style.setFont(font); // 设置自动换行; style.setWrapText(false); // 设置水平对齐的样式为居中对齐; style.setAlignment(CellStyle.ALIGN_CENTER); // 设置垂直对齐的样式为居中对齐; style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); return style; } }
当然也可以在web上使用,稍作修改即可
public static void xmlToExcel(String title, String[] headerArray, List<String[]> dataList, HttpServletResponse response) { OutputStream out = null; try { // 省略 ... String fileName = "test-" + System.currentTimeMillis() + ".xlsx"; // 设置导出文件名,固定格式 response.setHeader("Content-Disposition", "attachment;filename="+fileName); out = response.getOutputStream(); workbook.write(out); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }