要支持复制行图片,你需要进行以下修改:
在
copyRow()方法中,在复制单元格样式的同时,还需要复制单元格的图片。可以使用getDrawingPatriarch()方法获取绘图对象,并使用createAnchor()方法创建新的锚点(anchor),然后使用createPicture()方法将图片添加到新行的绘图对象中。在
mergeFileSheet()方法中,在复制附件内容之前,先检查附件是否包含图片。可以使用Workbook的hasPictures()方法判断工作簿是否包含图片,如果有图片,则通过getAllPictures()方法获取所有的图片,并在循环创建新行时,将图片一并复制到新的行上。
以下是修改后的代码片段示例:
private void mergeFileSheet(File originalFile, List<String> fileUrls) throws Exception {
try (FileInputStream fis = new FileInputStream(originalFile);
Workbook originalWorkbook = new XSSFWorkbook(fis)) {
for (String fileUrl : fileUrls) {
// 下载附件
byte[] fileContent = fastDfsClient.download(fileUrl);
String originalFilename = fastDfsClient.getOriginalFilename(fileUrl);
try (ByteArrayInputStream bais = new ByteArrayInputStream(fileContent);
Workbook attachmentWorkbook = new XSSFWorkbook(bais)) {
// 获取附件中sheet数量
int numberOfSheets = attachmentWorkbook.getNumberOfSheets();
int sheetIndex = 0;
for (int i = 0; i < numberOfSheets; i++) {
// 附件sheet
Sheet attachmentSheet = attachmentWorkbook.getSheetAt(i);
// 判断sheet是否为空
boolean sheetEmpty = ExcelUtil.isSheetEmpty(attachmentSheet);
if(sheetEmpty){
continue;
}
sheetIndex++;
String newSheetName = "附件-" + originalFilename.substring(0, originalFilename.lastIndexOf(".")) + "-" + sheetIndex;
// 创建新的sheet页来放置附件内容
Sheet newSheet = originalWorkbook.createSheet(newSheetName);
Drawing drawing = attachmentSheet.getDrawingPatriarch();
Drawing newDrawing = newSheet.createDrawingPatriarch();
for (Row sourceRow : attachmentSheet) {
Row targetRow = newSheet.createRow(sourceRow.getRowNum());
// 复制附件内容和图片
copyRow(sourceRow, targetRow, originalWorkbook, drawing, newDrawing);
}
}
}
}
// 写入修改后的Workbook到文件
try (FileOutputStream fos = new FileOutputStream(originalFile)) {
originalWorkbook.write(fos);
}
}
}
private void copyRow(Row source, Row target, Workbook workbook, Drawing sourceDrawing, Drawing targetDrawing) {
// 遍历源行的每个单元格
for (int i = source.getFirstCellNum(); i <= source.getLastCellNum(); i++) {
Cell sourceCell = source.getCell(i);
// 如果源单元格为null,则不创建新单元格
if (sourceCell != null) {
Cell targetCell = target.createCell(i, sourceCell.getCellType());
// 复制单元格样式(如果需要)
CellStyle sourceCellStyle = sourceCell.getCellStyle();
CellStyle targetCellStyle = workbook.createCellStyle();
targetCellStyle.cloneStyleFrom(sourceCellStyle);
targetCell.setCellStyle(targetCellStyle);
// 根据单元格类型复制值
switch (sourceCell.getCellTypeEnum()) {
case STRING:
targetCell.setCellValue(sourceCell.getStringCellValue());
break;
case NUMERIC:
targetCell.setCellValue(sourceCell.getNumericCellValue());
break;
case BOOLEAN:
targetCell.setCellValue(sourceCell.getBooleanCellValue());
break;
case FORMULA:
// 如果单元格是公式,则复制公式本身
targetCell.setCellFormula(sourceCell.getCellFormula());
break;
case BLANK:
// target.setCellType(CellType.BLANK);
break;
default:
// 默认处理
}
// 复制单元格图片(如果有)
if (sourceDrawing != null && sourceDrawing instanceof XSSFDrawing && targetDrawing != null) {
XSSFDrawing xssfSourceDrawing = (XSSFDrawing) sourceDrawing;
List<XSSFShape> shapes = xssfSourceDrawing.getShapes();
for (XSSFShape shape : shapes) {
if (shape instanceof XSSFPicture) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFClientAnchor anchor = picture.getClientAnchor();
int dx1 = anchor.getDx1();
int dy1 = anchor.getDy1();
int dx2 = anchor.getDx2();
int dy2 = anchor.getDy2();
XSSFClientAnchor newAnchor = newDrawing.createAnchor(dx1, dy1, dx2, dy2, anchor.getCol1(),
anchor.getRow1(), anchor.getCol2(),
anchor.getRow2());
PictureData pictureData = picture.getPictureData();
int pictureIndex = workbook.addPicture(pictureData.getData(), pictureData.getFormat());
newDrawing.createPicture(newAnchor, pictureIndex);
}
}
}
}
}
}
请注意,上述示例假设你使用的是Apache POI库,并且Excel文件中的图片类型为XSSF(即.xlsx格式)。如果你使用其他Excel处理库或者不同的文件格式,请相应调整代码。
内容由零声教学AI助手提供,问题来源于学员提问




