如何以.xlsx格式(Apache POI XSSF)插入Excel注释的背景图像?



有一个问题解决了如何使用HSSF Apache POI在2007年之前的版本中为Excel注释添加背景图像(格式.xsl(。

阿帕奇poi插入带图片的评论

但是查看文档,我找不到XSSF Apache POI(.xslx格式(的等效方法。

从HSSF移动到XSSF时,似乎删除了此关键方法:

HSSFComment        comment;
...
comment.setBackgroundImage(picIndex); // set picture as background image

使用XSSFComment的方法不支持。但是,如果一个人知道需要创造什么,那么这并非不可能。

首先,我们需要创建一个默认注释,如 Quick-Quide CellComments 所示。

然后我们需要将图片数据添加到此工作簿中,如快速指南图像所示。我们需要稍后添加引用的XSSFPictureData

然后我们需要获取 VML 绘图。XSSFComments存储在 VML 图形中,而不是默认XSSFDrawings中。这不是公开提供的,因此我们需要使用反射来执行此操作。

现在我们需要在 VML 绘图中设置与图片数据的关系。

最后,我们需要从 VML 绘图中获取注释形状,以设置该注释形状的填充以显示图片。对此没有高级方法。因此,我们需要使用低级com.microsoft.schemas.vml.*类的方法。

以下示例需要常见问题解答中所述的所有架构ooxml-schemas-1.4.jar的完整 jar。它使用apache poi 4.1.1进行测试。

完整示例:

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.util.IOUtils;
class CreateXSSFCommentWithPicture {
public static void main(String[] args) throws Exception {
try (XSSFWorkbook workbook = new XSSFWorkbook(); 
FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
// First we create a default XSSFComment:
XSSFCreationHelper factory = workbook.getCreationHelper();
XSSFSheet sheet = workbook.createSheet("Sheet");
XSSFRow row = sheet.createRow(3);
XSSFCell cell = row.createCell(5);
cell.setCellValue("F4");
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = factory.createClientAnchor();
anchor.setCol1(cell.getColumnIndex());
anchor.setCol2(cell.getColumnIndex()+2);
anchor.setRow1(row.getRowNum());
anchor.setRow2(row.getRowNum()+5);
XSSFComment comment = drawing.createCellComment(anchor);
XSSFRichTextString str = factory.createRichTextString("Hello, World!");
comment.setString(str);
comment.setAuthor("Apache POI");
// assign the comment to the cell
cell.setCellComment(comment);

// Now we put the image as fill of the comment's shape:
// add picture data to this workbook
InputStream is = new FileInputStream("samplePict.jpeg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = workbook.addPicture(bytes, XSSFWorkbook.PICTURE_TYPE_JPEG);
is.close();
// get picture data
XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx);
// get VML drawing
java.lang.reflect.Method getVMLDrawing = XSSFSheet.class.getDeclaredMethod("getVMLDrawing", boolean.class);
getVMLDrawing.setAccessible(true);
XSSFVMLDrawing vml = (XSSFVMLDrawing)getVMLDrawing.invoke(sheet, true);
// set relation to the picture data in VML drawing
org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart rp = vml.addRelation(null, XSSFRelation.IMAGES, pictureData);
// get comment shape
com.microsoft.schemas.vml.CTShape commentShape = vml.findCommentShape(cell.getRow().getRowNum(), cell.getColumnIndex());
// get fill of comment shape
com.microsoft.schemas.vml.CTFill fill = commentShape.getFillArray(0);
// already set color needs to be color2 now
fill.setColor2(fill.getColor());
fill.unsetColor();
// set relation Id of the picture
fill.setRelid(rp.getRelationship().getId());
// set some other properties
fill.setTitle("samplePict");
fill.setRecolor(com.microsoft.schemas.vml.STTrueFalse.T);
fill.setRotate(com.microsoft.schemas.vml.STTrueFalse.T);
fill.setType(com.microsoft.schemas.vml.STFillType.FRAME);
workbook.write(fileout);
}
}
}

据此,仅在HSSF中添加了图像到注释。

我想你将不得不使用另一种方法,比如在 apache poi 指南中。

最新更新