使用Apache POI复制Excel数据时如何保留原格式?
Apache POI复制单元格数据后丢失格式问题
使用Apache POI复制单元格数据时,数据已成功复制,但字体、前景色等格式全部丢失,尝试过以下方法均未解决:
尝试1:直接设置单元格样式属性
destCell.getCellStyle().setAlignment(srcCell.getCellStyle().getAlignment()); destCell.getCellStyle().setFont(srcCell.getCellStyle().getFont()); destCell.getCellStyle().setFillForegroundColor(srcCell.getCellStyle().getFillForegroundColorColor());
尝试2:单独创建XSSFFont并设置属性
XSSFFont font = new XSSFFont(); font.setFontName(srcSheet.getRow(currentRowIndex).getCell(currCellIndex).getCellStyle().getFont().getFontName()); font.setFontHeightInPoints(srcSheet.getRow(currentRowIndex).getCell(currCellIndex).getCellStyle().getFont().getFontHeightInPoints()); font.setColor(srcSheet.getRow(currentRowIndex).getCell(currCellIndex).getCellStyle().getFont().getColor()); font.setFamily(srcSheet.getRow(currentRowIndex).getCell(currCellIndex).getCellStyle().getFont().getFamily()); destSheet.getRow(currentRowIndex).getCell(currCellIndex).getCellStyle().setFont(font);
尝试3:直接赋值源单元格样式(报错)
destSheet.getRow(currentRowIndex).getCell(currCellIndex).setCellStyle(srcSheet.getRow(currentRowIndex).getCell(currentRowIndex).getCellStyle());
报错信息:
This Style does not belong to the supplied Workbook Styles Source. Are you trying to assign a style from one workbook to the cell of a different workbook?
效果对比
- 源格式:

- 复制后格式:

解决方案
核心问题:Apache POI里的CellStyle和Font是与所属Workbook绑定的,不能直接将源工作簿的样式/字体赋值给目标工作簿的单元格,必须在目标工作簿中新建样式和字体,逐一复制源属性。
1. 实现字体复制工具方法
将源字体的所有需要的属性复制到目标工作簿的新字体中:
private static XSSFFont copyFont(XSSFWorkbook destWorkbook, XSSFFont srcFont) { XSSFFont destFont = destWorkbook.createFont(); // 基础字体属性 destFont.setFontName(srcFont.getFontName()); destFont.setFontHeightInPoints(srcFont.getFontHeightInPoints()); destFont.setColor(srcFont.getColor()); destFont.setFamily(srcFont.getFamily()); // 额外样式属性 destFont.setBold(srcFont.getBold()); destFont.setItalic(srcFont.getItalic()); destFont.setStrikeout(srcFont.getStrikeout()); destFont.setUnderline(srcFont.getUnderline()); return destFont; }
2. 实现单元格样式复制工具方法
复制源样式的对齐、填充、边框、字体等所有属性到目标工作簿的新样式:
private static XSSFCellStyle copyCellStyle(XSSFWorkbook destWorkbook, XSSFCellStyle srcStyle) { XSSFCellStyle destStyle = destWorkbook.createCellStyle(); // 对齐方式 destStyle.setAlignment(srcStyle.getAlignment()); destStyle.setVerticalAlignment(srcStyle.getVerticalAlignment()); // 填充颜色和模式 destStyle.setFillForegroundColor(srcStyle.getFillForegroundColorColor()); destStyle.setFillPattern(srcStyle.getFillPattern()); // 边框样式和颜色 destStyle.setBorderTop(srcStyle.getBorderTop()); destStyle.setBorderBottom(srcStyle.getBorderBottom()); destStyle.setBorderLeft(srcStyle.getBorderLeft()); destStyle.setBorderRight(srcStyle.getBorderRight()); destStyle.setTopBorderColor(srcStyle.getTopBorderColorColor()); destStyle.setBottomBorderColor(srcStyle.getBottomBorderColorColor()); destStyle.setLeftBorderColor(srcStyle.getLeftBorderColorColor()); destStyle.setRightBorderColor(srcStyle.getRightBorderColorColor()); // 绑定复制好的字体 destStyle.setFont(copyFont(destWorkbook, (XSSFFont) srcStyle.getFont())); // 数据格式(比如数值、日期格式) destStyle.setDataFormat(srcStyle.getDataFormat()); return destStyle; }
3. 复制单元格时应用样式
复制完单元格数据后,调用上述方法生成新样式并设置给目标单元格:
// 先复制单元格数据(根据实际单元格类型调整) if (srcCell.getCellType() == CellType.STRING) { destCell.setCellValue(srcCell.getStringCellValue()); } else if (srcCell.getCellType() == CellType.NUMERIC) { destCell.setCellValue(srcCell.getNumericCellValue()); } // ...其他单元格类型处理 // 复制样式 XSSFWorkbook destWorkbook = (XSSFWorkbook) destSheet.getWorkbook(); XSSFCellStyle newStyle = copyCellStyle(destWorkbook, (XSSFCellStyle) srcCell.getCellStyle()); destCell.setCellStyle(newStyle);
优化建议
如果要复制大量单元格,建议用Map<XSSFCellStyle, XSSFCellStyle>缓存已复制的样式,避免重复创建相同样式,提升性能。
内容的提问来源于stack exchange,提问作者poojay
相关产品推荐
相关产品推荐

