Я реализовал некоторый код для копирования рабочих книг независимо от их типа: он использует интерфейсы, поэтому вы можете использовать HSSFWorkbook, XSSFWorkbook и SXSSFWorkbook.
Это копирует листы с изображениями, шрифтами, стилями и строками: для моегоВ случае использования мне нужно вставить новые строки в существующий шаблон и записать в SXSSFWorkbook, поэтому я не копирую все листы и строки напрямую, а вместо этого выбираю листы, которые хочу скопировать, а затем копирую нужные ему части.
Workbook template = getTemplateSource(...);
Workbook wb = new SXSSFWorkbook(...);
ExcelTemplate builder = new ExcelTemplate(template);
int sheetIndex = ...;
Sheet srcSheet = template.getSheetAt(sheetIndex);
Sheet dstSheet = ExcelTemplate.copySheet(template, wb, sheetIndex);
int rowNumber = getDataInsertionRow();
int foot = rowNumber + 1;
builder.copyRows(wb, srcSheet, dstSheet, 0, rowNumber, 0);
for (....) {
writeNewRows(dstSheet, rowNumber++, data);
}
builder.copyRows(wb, srcSheet, dstSheet, foot, srcSheet.getLastRowNum() + 1, rowNumber);
А вот код (я пытался удалить все свои тесты, но, возможно, я забыл некоторые неиспользуемые строки)
package com.systemonenoc.billing.web.view;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Shape;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class ExcelTemplate {
private final Workbook template;
private final Map<Integer, Font> fonts = new HashMap<>();
private final Map<Integer, CellStyle> styles = new HashMap<>();
public ExcelTemplate(Workbook template) {
this.template = template;
}
public void switchStyles(Workbook dstWorkbook, CellStyle[] styles) {
for (int i = 0; i < styles.length; i++) {
styles[i] = getStyle(dstWorkbook, styles[i]);
}
}
private Font getFont(Workbook dstWorkbook, Font font) {
return fonts.computeIfAbsent(font.hashCode(), k -> cloneFont(dstWorkbook, font));
}
private CellStyle getStyle(Workbook dstWorkbook, CellStyle style) {
Font font = getFont(dstWorkbook, template.getFontAt(style.getFontIndex()));
return styles.computeIfAbsent(style.hashCode(), k -> cloneStyle(dstWorkbook, style, dstWorkbook.createDataFormat(), font));
}
public void copyRows(Workbook dstWorkbook, Sheet srcSheet, Sheet dstSheet, int from, int to, int offset) {
for (int r = from; r < to; r++) {
Row srcRow = srcSheet.getRow(r);
if (srcRow != null) {
CellStyle style = srcRow.getRowStyle();
Row dstRow = dstSheet.createRow(r + offset);
dstRow.setHeight(srcRow.getHeight());
if (style != null) {
dstRow.setRowStyle(getStyle(dstWorkbook, style));
}
for (int c = 0; c < srcRow.getLastCellNum(); c++) {
Cell srcCell = srcRow.getCell(c);
if (srcCell != null) {
int type = getCellType(srcCell);
Object value = getCellValue(srcCell);
style = srcCell.getCellStyle();
Cell newCell = dstRow.createCell(c, type);
setCellValue(newCell, value, type);
newCell.setCellStyle(getStyle(dstWorkbook, style));
}
}
}
}
}
public static Sheet copySheet(Workbook srcWorkbook, Workbook dstWorkbook, int sheetIndex) {
Sheet srcSheet = srcWorkbook.getSheetAt(sheetIndex);
Sheet dstSheet = dstWorkbook.createSheet(srcSheet.getSheetName());
dstSheet.setDisplayFormulas(srcSheet.isDisplayFormulas());
dstSheet.setDisplayGridlines(srcSheet.isDisplayGridlines());
dstSheet.setDisplayGuts(srcSheet.getDisplayGuts());
dstSheet.setDisplayRowColHeadings(srcSheet.isDisplayRowColHeadings());
dstSheet.setDisplayZeros(srcSheet.isDisplayZeros());
dstSheet.setFitToPage(srcSheet.getFitToPage());
dstSheet.setForceFormulaRecalculation(srcSheet.getForceFormulaRecalculation());
dstSheet.setHorizontallyCenter(srcSheet.getHorizontallyCenter());
dstSheet.setMargin(Sheet.BottomMargin, srcSheet.getMargin(Sheet.BottomMargin));
dstSheet.setMargin(Sheet.FooterMargin, srcSheet.getMargin(Sheet.FooterMargin));
dstSheet.setMargin(Sheet.HeaderMargin, srcSheet.getMargin(Sheet.HeaderMargin));
dstSheet.setMargin(Sheet.LeftMargin, srcSheet.getMargin(Sheet.LeftMargin));
dstSheet.setMargin(Sheet.RightMargin, srcSheet.getMargin(Sheet.RightMargin));
dstSheet.setMargin(Sheet.TopMargin, srcSheet.getMargin(Sheet.TopMargin));
dstSheet.setPrintGridlines(srcSheet.isPrintGridlines());
dstSheet.setRightToLeft(srcSheet.isRightToLeft());
dstSheet.setRowSumsBelow(srcSheet.getRowSumsBelow());
dstSheet.setRowSumsRight(srcSheet.getRowSumsRight());
dstSheet.setVerticallyCenter(srcSheet.getVerticallyCenter());
for (int i = 0; i < 20; i++) {
dstSheet.setColumnWidth(i, srcSheet.getColumnWidth(i));
dstSheet.setColumnHidden(i, srcSheet.isColumnHidden(i));
}
srcSheet.getMergedRegions().forEach(dstSheet::addMergedRegion);
Drawing<?> d1 = srcSheet.getDrawingPatriarch();
if (d1 != null) {
Drawing<?> d2 = dstSheet.getDrawingPatriarch();
if (d2 == null) {
d2 = dstSheet.createDrawingPatriarch();
}
for (Shape shape : d1) {
if (shape instanceof Picture) {
Picture p = (Picture) shape;
ClientAnchor a1 = p.getClientAnchor();
int pictureId = dstWorkbook.addPicture(p.getPictureData().getData(), p.getPictureData().getPictureType());
ClientAnchor a2 = d2.createAnchor(a1.getDx1(), a1.getDy1(), a1.getDx2(), a1.getDy2(), a1.getCol1(), a1.getRow1(), a1.getCol2(), a1.getRow2());
d2.createPicture(a2, pictureId);
}
}
}
return dstSheet;
}
public static Font cloneFont(Workbook dstWorkbook, Font font) {
Font clone = dstWorkbook.createFont();
clone.setBold(font.getBold());
clone.setCharSet(font.getCharSet());
clone.setColor(font.getColor());
clone.setFontHeight(font.getFontHeight());
clone.setFontName(font.getFontName());
clone.setItalic(font.getItalic());
clone.setStrikeout(font.getStrikeout());
clone.setTypeOffset(font.getTypeOffset());
clone.setUnderline(font.getUnderline());
return clone;
}
public static CellStyle cloneStyle(Workbook dstWorkbook, CellStyle style, DataFormat formatter, Font font) {
CellStyle clone = dstWorkbook.createCellStyle();
clone.setAlignment(style.getAlignmentEnum());
clone.setBorderBottom(style.getBorderBottomEnum());
clone.setBorderLeft(style.getBorderLeftEnum());
clone.setBorderRight(style.getBorderRightEnum());
clone.setBorderTop(style.getBorderTopEnum());
clone.setDataFormat(formatter.getFormat(style.getDataFormatString()));
clone.setFillBackgroundColor(style.getFillBackgroundColor());
clone.setFillForegroundColor(style.getFillForegroundColor());
clone.setFillPattern(style.getFillPatternEnum());
clone.setFont(font);
clone.setHidden(style.getHidden());
clone.setIndention(style.getIndention());
clone.setLocked(style.getLocked());
clone.setVerticalAlignment(style.getVerticalAlignmentEnum());
clone.setWrapText(style.getWrapText());
return clone;
}
protected static int getCellType(Cell cell) {
int cellType = cell.getCellType();
if (cellType == Cell.CELL_TYPE_FORMULA) {
cellType = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator()
.evaluateFormulaCell(cell);
}
return cellType;
}
protected static Object getCellValue(Cell cell) {
switch (getCellType(cell)) {
case Cell.CELL_TYPE_BLANK:
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue();
case Cell.CELL_TYPE_ERROR:
return cell.getErrorCellValue();
case Cell.CELL_TYPE_NUMERIC:
return cell.getNumericCellValue();
}
return null;
}
protected static void setCellValue(Cell cell, Object value, int type) {
switch (type) {
case Cell.CELL_TYPE_BLANK:
return;
case Cell.CELL_TYPE_STRING:
cell.setCellValue((String) value);
return;
case Cell.CELL_TYPE_BOOLEAN:
cell.setCellValue((Boolean) value);
return;
case Cell.CELL_TYPE_ERROR:
cell.setCellErrorValue((Byte) value);
return;
case Cell.CELL_TYPE_NUMERIC:
cell.setCellValue((Double) value);
return;
}
}
}