当前位置: 首页 > 知识库问答 >
问题:

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

孔阳平
2023-03-14

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

apache poi插入带图片的注释

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

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

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

共有1个答案

澹台季萌
2023-03-14

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

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

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

然后我们需要得到VML图纸<代码>XSSF命令存储在VML图形中,而不是默认的XSSF图形。这不是公共提供的,所以我们需要使用反射来实现。

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

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

下面的示例需要FAQ中提到的所有模式ooxml-schemas-1.4.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);
  }

 }
}
 类似资料:
  • 我有一个像这样的excel格式: 我有两个函数来填充数据。这个是填充细节。 这个用来填充总数 问题是,如果我有超过5条记录,数据将被填充到第20行,我的格式被破坏。我的预期结果是,如果有超过5条记录,那么它将为每个添加的记录添加2行(作为格式),并且我的SUM始终是工作表的最后2行。 我正在考虑将 SUM 性别删除到另一个工作表中,并将其复制到最后一个工作表中,直到详细信息完成。但是我遇到了一些问

  • 问题内容: 我想在ng-repeat块中添加带有插值表达式的HTML注释。但是,当我尝试执行此操作时,不会对表达式进行插值。例如: 当我查看DOM(即Chrom DevTools中的Elements标签)时,我只看到未插补的字符串(“ {{item.id}}”)而不是插补的值。 这里正确的语法是什么? 问题答案: 这是一种矫kill过正的方法,因为您可以只使用或类似注释中的建议,但是这只是一个有趣

  • 我正在使用Apache Poi将数据写入Excel表格。我需要合并单元格并为合并的单元格设置背景。我有合并单元格的代码,但我不知道如何为单元格设置背景或前景。 //此代码是我用于合并单元格和设置单元格边框的代码

  • 问题内容: 我一直试图通过css更改输入按钮的背景图像,但是它不起作用。 search.html: search.css: 有什么问题吗? 甚至内联css似乎也不起作用。 问题答案: 您需要输入不带单词的单词。 两种方法都经过测试,这一方法可行。 例:

  • 问题内容: 我有一个正在编写的CSS页面,我需要在一个类中应用背景图像,然后使用另一个类将一个局部透明的背景图像放在已经存在的背景图像之上。这只是一个简单的字眼,所以让我做一个示范。 在此示例中,第一个div应该具有背景图像1,第二个div应该具有背景图像1,但是滤镜图像位于其顶部,然后第三个div应该是图像2,第四个应该是图像2并且上面具有相同的滤镜。 但是,在此示例中,.backgroundF

  • 现在,我使用默认配置,当我按下“命令”+“/”时,“//”显示在第一列,请参见图片中的第二行。 如何更改配置以在代码开头显示“//”并在后面显示空格?就像第一句台词一样。