Apache poi 多行复制,复制模板行
背景
在Excel中渲染批量数据,其中一条数据会占多行的空间,多行的表体为一个模板,需要保持这个模板的样式(包括合并行,合并列)不变在下根据数据量复制相应量的多行模板如下图:
同时还需要复制合并列的需求,但是还没想好怎么做╮(╯_╰)╭
/**
* 添加模板行,并保持连续性
* @param sheet
* @param startRowIndex 模板行开始index 如上图是 11行,所以这里是 10
* @param endRowIndex 模板行结束 index 上图是13行 所以这里是13
* @param lines 要复制的行数,就是数据个数
*/
public static void addTemplateRow(Sheet sheet, int startRowIndex, int endRowIndex, int lines){
for (int line = 0; line < lines; line++) {
sheet.shiftRows(endRowIndex + 1, sheet.getLastRowNum(), lines*(endRowIndex - startRowIndex) + 1, true, false);
// 逐行复制
for (int i = startRowIndex; i <= endRowIndex; i++) {
copyRowWithMergedCells(sheet, i, i + (endRowIndex - startRowIndex + 1));
}
}
}
private static void copyRowWithMergedCells(Sheet worksheet, int sourceRowIndex, int targetRowIndex) {
// 获取源行和目标行
Row sourceRow = worksheet.getRow(sourceRowIndex);
Row newRow = worksheet.createRow(targetRowIndex);
// 复制行高
newRow.setHeight(sourceRow.getHeight());
// 循环复制单元格
for (int colIndex = 0; colIndex < sourceRow.getLastCellNum(); colIndex++) {
Cell sourceCell = sourceRow.getCell(colIndex);
Cell newCell = newRow.createCell(colIndex);
if (sourceCell != null) {
// 复制单元格样式
newCell.setCellStyle(sourceCell.getCellStyle());
// 处理合并单元格
int numMergedRegions = worksheet.getNumMergedRegions();
for (int i = 0; i < numMergedRegions; i++) {
CellRangeAddress mergedRegion = worksheet.getMergedRegion(i);
if (isCellInMergedRegion(sourceCell, mergedRegion)) {
// 处理合并单元格
int firstRow = mergedRegion.getFirstRow() - sourceRowIndex + targetRowIndex;
int lastRow = mergedRegion.getLastRow() - sourceRowIndex + targetRowIndex;
int firstCol = mergedRegion.getFirstColumn();
int lastCol = mergedRegion.getLastColumn();
CellRangeAddress newMergedRegion = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
worksheet.addMergedRegion(newMergedRegion);
break; // 仅处理第一个匹配的合并单元格
}
}
newCell.setCellValue(sourceCell.getRichStringCellValue());
}
}
}
private static boolean isCellInMergedRegion(Cell cell, CellRangeAddress mergedRegion) {
return cell.getRowIndex() >= mergedRegion.getFirstRow() && cell.getRowIndex() <= mergedRegion.getLastRow()
&& cell.getColumnIndex() >= mergedRegion.getFirstColumn() && cell.getColumnIndex() <= mergedRegion.getLastColumn();
}