http://t.csdnimg.cn/Axn4Phttp://t.csdnimg.cn/Axn4P建议:从入门看起会更好理解POI对Excel数据的使用和处理
记得引入依赖:
org.apache.poi poi 4.0.1 org.apache.poi poi-ooxml 4.0.1 org.apache.poi poi-ooxml-schemas 4.0.1
// JUnit的@Test注解表示这是一个测试方法 @Test void testExcel() throws IOException { // 创建一个新的XSSFWorkbook对象,这是操作Excel文件的核心类 XSSFWorkbook workbook = new XSSFWorkbook(); // 在工作簿中创建一个名为"sheet1"的工作表 XSSFSheet sheet = workbook.createSheet("sheet1"); // 在工作表中创建第三行(行索引从0开始) Row row = sheet.createRow(2); // 在该行中创建第三个单元格(列索引从0开始) Cell cell = row.createCell(2); // 设置单元格的值为"Hello World 2024" cell.setCellValue("Hello World 2024"); // 创建一个单元格样式 CellStyle cellStyle = workbook.createCellStyle(); // 设置单元格的上下左右边框为细线 cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); // 创建一个字体对象 Font font = workbook.createFont(); // 设置字体为"宋体" font.setFontName("宋体"); // 设置字体大小为32磅 font.setFontHeightInPoints((short) 32); // 将字体应用到单元格样式中 cellStyle.setFont(font); // 设置行高为50磅 row.setHeightInPoints((short) 50); // 设置第三列的宽度为100 * 365(单位是1/256个字符宽度) sheet.setColumnWidth(2, 100 * 365); // 将单元格样式应用到单元格上 cell.setCellStyle(cellStyle); // 创建一个文件输出流,用于将Excel文件写入磁盘 FileOutputStream out = new FileOutputStream("D:\\Desktop\\JavaCode\\poi-demo\\src\\main\\resources\\test.xlsx"); // 将工作簿写入输出流 workbook.write(out); // 关闭输出流 out.close(); }
// JUnit的@Test注解表示这是一个测试方法 @Test void testDrawExcel() throws IOException { // 创建一个新的XSSFWorkbook对象,这是操作Excel文件的核心类 XSSFWorkbook workbook = new XSSFWorkbook(); // 在工作簿中创建一个名为"sheet1"的工作表 XSSFSheet sheet = workbook.createSheet("sheet1"); // 创建一个文件输入流,用于读取图片文件 FileInputStream in = new FileInputStream("D:\\Desktop\\test.jpg"); // 创建一个字节数组,长度为图片文件的大小 byte[] bytes = new byte[in.available()]; // 读取图片文件到字节数组 in.read(bytes); // 关闭输入流 in.close(); // 将图片添加到工作簿,并返回图片的索引 int index = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); // 获取创建助手,用于创建绘图对象 CreationHelper helper = workbook.getCreationHelper(); // 创建绘图对象,用于在工作表中绘制图片 XSSFDrawing drawing = sheet.createDrawingPatriarch(); // 创建客户端锚点,用于指定图片的位置 ClientAnchor anchor = helper.createClientAnchor(); // 设置图片的起始行 anchor.setRow1(0); // 设置图片的起始列 anchor.setCol1(1); // 创建图片对象,并将其插入到工作表中 XSSFPicture picture = drawing.createPicture(anchor, index); // 调整图片大小以适应单元格 picture.resize(); // 创建一个文件输出流,用于将Excel文件写入磁盘 FileOutputStream out = new FileOutputStream("D:\\Desktop\\JavaCode\\poi-demo\\src\\main\\resources\\test.xlsx"); // 将工作簿写入输出流 workbook.write(out); // 关闭输出流 out.close(); }
如何想根据模版进行创建Excel表格。而不是直接覆盖创建新的Excel表格的方式:
// JUnit的@Test注解表示这是一个测试方法 @Test void testDrawExcel() throws IOException { // 使用Spring的ClassPathResource来加载类路径下的资源文件 Resource resource = new ClassPathResource("test.xlsx"); // 获取资源文件的FileInputStream FileInputStream resourceIn = new FileInputStream(resource.getFile()); // 使用FileInputStream加载现有工作簿 XSSFWorkbook workbook = new XSSFWorkbook(resourceIn); // 获取工作簿中的第一个工作表 XSSFSheet sheet = workbook.getSheetAt(0); // 创建一个文件输入流,用于读取图片文件 FileInputStream in = new FileInputStream("D:\\Desktop\\test.jpg"); // 创建一个字节数组,长度为图片文件的大小 byte[] bytes = new byte[in.available()]; // 读取图片文件到字节数组 in.read(bytes); // 关闭输入流 in.close(); // 将图片添加到工作簿,并返回图片的索引 int index = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG); // 获取创建助手,用于创建绘图对象 CreationHelper helper = workbook.getCreationHelper(); // 获取工作表中的绘图对象,如果没有则创建 Drawing> drawing = sheet.createDrawingPatriarch(); // 创建客户端锚点,用于指定图片的位置 ClientAnchor anchor = helper.createClientAnchor(); // 设置图片的起始行为第11行(行索引从0开始) anchor.setRow1(10); // 设置图片的起始列为第2列(列索引从0开始) anchor.setCol1(1); // 创建图片对象,并将其插入到工作表中 Picture picture = drawing.createPicture(anchor, index); // 调整图片大小以适应单元格 picture.resize(); // 创建一个文件输出流,用于将Excel文件写入磁盘 FileOutputStream out = new FileOutputStream("D:\\Desktop\\JavaCode\\poi-demo\\src\\main\\resources\\test.xlsx"); // 将工作簿写入输出流 workbook.write(out); // 关闭输出流 out.close(); }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ExcelAttribute { /** 对应的列名称 */ String name() default ""; /** 列序号 */ int sort(); /** 字段类型对应的格式 */ String format() default ""; }
public class ExcelExportUtil { private int rowIndex; private int styleIndex; private String templatePath; private Class clazz; private Field fields[]; public ExcelExportUtil(Class clazz,int rowIndex,int styleIndex) { this.clazz = clazz; this.rowIndex = rowIndex; this.styleIndex = styleIndex; fields = clazz.getDeclaredFields(); } /** * 基于注解导出 */ public void export(HttpServletResponse response,InputStream is, List objs,String fileName) throws Exception { XSSFWorkbook workbook = new XSSFWorkbook(is); Sheet sheet = workbook.getSheetAt(0); CellStyle[] styles = getTemplateStyles(sheet.getRow(styleIndex)); AtomicInteger datasAi = new AtomicInteger(rowIndex); for (T t : objs) { Row row = sheet.createRow(datasAi.getAndIncrement()); for(int i=0;i
public class ExcelImportUtil { private Class clazz; private Field fields[]; public ExcelImportUtil(Class clazz) { this.clazz = clazz; fields = clazz.getDeclaredFields(); } /** * 基于注解读取excel */ public List readExcel(InputStream is, int rowIndex,int cellIndex) { List list = new ArrayList(); T entity = null; try { XSSFWorkbook workbook = new XSSFWorkbook(is); Sheet sheet = workbook.getSheetAt(0); // 不准确 int rowLength = sheet.getLastRowNum(); System.out.println(sheet.getLastRowNum()); for (int rowNum = rowIndex; rowNum <= sheet.getLastRowNum(); rowNum++) { Row row = sheet.getRow(rowNum); entity = (T) clazz.newInstance(); System.out.println(row.getLastCellNum()); for (int j = cellIndex; j < row.getLastCellNum(); j++) { Cell cell = row.getCell(j); for (Field field : fields) { if(field.isAnnotationPresent(ExcelAttribute.class)){ field.setAccessible(true); ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class); if(j == ea.sort()) { field.set(entity, covertAttrType(field, cell)); } } } } list.add(entity); } } catch (Exception e) { e.printStackTrace(); } return list; } /** * 类型转换 将cell 单元格格式转为 字段类型 */ private Object covertAttrType(Field field, Cell cell) throws Exception { String fieldType = field.getType().getSimpleName(); if ("String".equals(fieldType)) { return getValue(cell); }else if ("Date".equals(fieldType)) { return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(getValue(cell)) ; }else if ("int".equals(fieldType) || "Integer".equals(fieldType)) { return Integer.parseInt(getValue(cell)); }else if ("double".equals(fieldType) || "Double".equals(fieldType)) { return Double.parseDouble(getValue(cell)); }else { return null; } } /** * 格式转为String * @param cell * @return */ public String getValue(Cell cell) { if (cell == null) { return ""; } switch (cell.getCellType()) { case STRING: return cell.getRichStringCellValue().getString().trim(); case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { Date dt = DateUtil.getJavaDate(cell.getNumericCellValue()); return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(dt); } else { // 防止数值变成科学计数法 String strCell = ""; Double num = cell.getNumericCellValue(); BigDecimal bd = new BigDecimal(num.toString()); if (bd != null) { strCell = bd.toPlainString(); } // 去除 浮点型 自动加的 .0 if (strCell.endsWith(".0")) { strCell = strCell.substring(0, strCell.indexOf(".")); } return strCell; } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); default: return ""; } }
在User实体上对导出的字段名加上自定义注解@ExcelAttribute(序列号)
List list = new ExcelImportUtil(User.class).readExcel(is, 1, 2);
@GetMapping("/export/{month}") public void export(@PathVariable(name = "month") String month) throws Exception { //1.构造数据 List list = userCompanyPersonalService.findByReport(companyId,month+"%"); //2.加载模板流数据 Resource resource = new ClassPathResource("excel-template/hr-demo.xlsx"); FileInputStream fis = new FileInputStream(resource.getFile()); new ExcelExportUtil(EmployeeReportResult.class,2,2). export(response,fis,list,"人事报表.xlsx"); }
SXSSF和XSSF都是Apache POI库中用于处理Excel文件的API,它们属于POI项目中用于操作Excel 2007 OOXML (.xlsx)文件的组件。以下是SXSSF和XSSF的主要区别:
内存使用:
性能:
功能限制:
使用场景:
/自定义Sheet基于Sax的解析处理器 public class SheetHandler implements XSSFSheetXMLHandler.SheetContentsHandler { //封装实体对象 private PoiEntity entity; /** * 解析行开始 */ @Override public void startRow(int rowNum) { if (rowNum >0 ) { entity = new PoiEntity(); } } /* * 解析每一个单元格 */ @Override public void cell(String cellReference, String formattedValue, XSSFComment comment) { if(entity != null) { switch (cellReference.substring(0, 1)) { case "A": entity.setId(formattedValue); break; case "B": entity.setBreast(formattedValue); break; case "C": entity.setAdipocytes(formattedValue); break; case "D": entity.setNegative(formattedValue); break; case "E": entity.setStaining(formattedValue); break; case "F": entity.setSupportive(formattedValue); break; default: break; } } } /** * 解析行结束 */ public void endRow(int rowNum) { System.out.println(entity); } //处理头尾 public void headerFooter(String text, boolean isHeader, String tagName) { } }
/** * 自定义Excel解析器 */ public class ExcelParser { public void parse (String path) throws Exception { //1.根据Excel获取OPCPackage对象 OPCPackage pkg = OPCPackage.open(path, PackageAccess.READ); try { //2.创建XSSFReader对象 XSSFReader reader = new XSSFReader(pkg); //3.获取SharedStringsTable对象 SharedStringsTable sst = reader.getSharedStringsTable(); //4.获取StylesTable对象 StylesTable styles = reader.getStylesTable(); //5.创建Sax的XmlReader对象 XMLReader parser = XMLReaderFactory.createXMLReader(); //6.设置处理器 parser.setContentHandler(new XSSFSheetXMLHandler(styles,sst, new SheetHandler(), false)); XSSFReader.SheetIterator sheets = (XSSFReader.SheetIterator) reader.getSheetsData(); //7.逐行读取 while (sheets.hasNext()) { InputStream sheetstream = sheets.next(); InputSource sheetSource = new InputSource(sheetstream); try { parser.parse(sheetSource); } finally { sheetstream.close(); } } } finally { pkg.close(); } } }