我正在try 使用Java中的ApachePOI将图像添加到工作表的页眉. 注意:我可以将图像添加到特定的单元格,但我想将其添加到页眉.

我try 了以下代码,但似乎不起作用:

private void createOverview(final XSSFWorkbook workbook) {
        final Sheet overview = xlsxService.createSheet(messages.format("excel.overview"), workbook);
        //...
        final Header header = overview.getHeader();
        header.setRight(LOGO_852_X_558_PNG);

        // set footer
        final Footer footer = overview.getFooter();
        footer.setCenter("page " + HeaderFooter.page() + " of " + HeaderFooter.numPages());
    }

此代码不会引发任何错误,但图像不会出现在工作表的页眉中.我知道ApachePOI中Header类的setright()、setCenter()和setLeft()方法是为处理文本而不是图像而设计的.

在ApachePOI中,有没有办法将图像添加到工作表的页眉?如果没有,是否有解决办法或备用库来支持此功能?

任何帮助都将不胜感激.谢谢!

推荐答案

原则是这样回答的:apache POI adding watermark in Excel workbook.

唯一的区别是标题图形的位置--右边而不是中间--和图片的大小.

完整的示例:

import java.io.*;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import org.apache.poi.util.IOUtils;
import org.apache.poi.ss.util.ImageUtils;

import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;

import org.apache.xmlbeans.XmlObject;

import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;

public class CreateExcelPictureInHeader {

 static void createPictureForHeader(XSSFSheet sheet, int pictureIdx, String pictureTitle, int vmlIdx, String headerPos, double scale) throws Exception {
  OPCPackage opcpackage = sheet.getWorkbook().getPackage();

  //creating /xl/drawings/vmlDrawing1.vml
  PackagePartName partname = PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing" + vmlIdx+ ".vml");
  PackagePart part = opcpackage.createPart(partname, "application/vnd.openxmlformats-officedocument.vmlDrawing");
  //creating new VmlDrawing
  VmlDrawing vmldrawing = new VmlDrawing(part);

  //creating the relation to the picture in /xl/drawings/_rels/vmlDrawing1.vml.rels
  XSSFPictureData picData = sheet.getWorkbook().getAllPictures().get(pictureIdx);
  String rIdPic = vmldrawing.addRelation(null, XSSFRelation.IMAGES, picData).getRelationship().getId();

  //get image dimension
  ByteArrayInputStream is = new ByteArrayInputStream(picData.getData());
  java.awt.Dimension imageDimension = ImageUtils.getImageDimension(is, picData.getPictureType());
  is.close();
  
  //scale image dimension
  imageDimension.setSize(imageDimension.getWidth() * scale, imageDimension.getHeight() * scale);

  //updating the VmlDrawing
  vmldrawing.setRIdPic(rIdPic);
  vmldrawing.setPictureTitle(pictureTitle);
  vmldrawing.setImageDimension(imageDimension);
  vmldrawing.setHeaderPos(headerPos);

  //creating the relation to /xl/drawings/vmlDrawing1.xml in /xl/worksheets/_rels/sheet1.xml.rels
  String rIdExtLink = sheet.addRelation(null, XSSFRelation.VML_DRAWINGS, vmldrawing).getRelationship().getId();

  //creating the <legacyDrawingHF r:id="..."/> in /xl/worksheets/sheetN.xml
  sheet.getCTWorksheet().addNewLegacyDrawingHF().setId(rIdExtLink);

 }

 public static void main(String[] args) throws Exception {

  Workbook workbook = new XSSFWorkbook();

  Sheet sheet;
  Header header;
  InputStream is;
  byte[] bytes;

  int pictureIdx; //we need it later

  sheet = workbook.createSheet();
  
  sheet.createRow(0).createCell(0).setCellValue("A1");

  header = sheet.getHeader();
  header.setRight("&G"); // &G means Graphic

  //add picture data to this workbook
  is = new FileInputStream("./logo.png");
  bytes = IOUtils.toByteArray(is);
  pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
  is.close();

  //create header picture from picture data of this workbook
  createPictureForHeader((XSSFSheet)sheet, pictureIdx, "logo", 1, "RH"/*RightHeader*/, 0.5d);

  FileOutputStream out = new FileOutputStream("CreateExcelPictureInHeader.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();    
 }

 //class for VmlDrawing
 static class VmlDrawing extends POIXMLDocumentPart {

  String rIdPic = "";
  String pictureTitle = "";
  java.awt.Dimension imageDimension = null;
  String headerPos = "";

  VmlDrawing(PackagePart part) {
   super(part);
  }

  void setRIdPic(String rIdPic) {
   this.rIdPic = rIdPic;
  }

  void setPictureTitle(String pictureTitle) {
   this.pictureTitle = pictureTitle;
  }

  void setHeaderPos(String headerPos) {
   this.headerPos = headerPos;
  }

  void setImageDimension(java.awt.Dimension imageDimension) {
   this.imageDimension = imageDimension;
  }

  @Override
  protected void commit() throws IOException {
   PackagePart part = getPackagePart();
   OutputStream out = part.getOutputStream();
   try {
    XmlObject doc = XmlObject.Factory.parse(

      "<xml xmlns:v=\"urn:schemas-microsoft-com:vml\""
     +" xmlns:o=\"urn:schemas-microsoft-com:office:office\""
     +" xmlns:x=\"urn:schemas-microsoft-com:office:excel\">"
     +" <o:shapelayout v:ext=\"edit\">"
     +"  <o:idmap v:ext=\"edit\" data=\"1\"/>"
     +" </o:shapelayout><v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\""
     +"  o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">"
     +"  <v:stroke joinstyle=\"miter\"/>"
     +"  <v:formulas>"
     +"   <v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>"
     +"   <v:f eqn=\"sum @0 1 0\"/>"
     +"   <v:f eqn=\"sum 0 0 @1\"/>"
     +"   <v:f eqn=\"prod @2 1 2\"/>"
     +"   <v:f eqn=\"prod @3 21600 pixelWidth\"/>"
     +"   <v:f eqn=\"prod @3 21600 pixelHeight\"/>"
     +"   <v:f eqn=\"sum @0 0 1\"/>"
     +"   <v:f eqn=\"prod @6 1 2\"/>"
     +"   <v:f eqn=\"prod @7 21600 pixelWidth\"/>"
     +"   <v:f eqn=\"sum @8 21600 0\"/>"
     +"   <v:f eqn=\"prod @7 21600 pixelHeight\"/>"
     +"   <v:f eqn=\"sum @10 21600 0\"/>"
     +"  </v:formulas>"
     +"  <v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>"
     +"  <o:lock v:ext=\"edit\" aspectratio=\"t\"/>"
     +" </v:shapetype><v:shape id=\"" + headerPos + "\" o:spid=\"_x0000_s1025\" type=\"#_x0000_t75\""
     +"  style='position:absolute;margin-left:0;margin-top:0;"
     +"width:" + (int)imageDimension.getWidth() + "px;height:" + (int)imageDimension.getHeight() + "px;"
     +"z-index:1'>"
     +"  <v:imagedata o:relid=\""+ rIdPic + "\" o:title=\"" + pictureTitle + "\"/>"
     +"  <o:lock v:ext=\"edit\" rotation=\"t\"/>"
     +" </v:shape></xml>"

    );
    doc.save(out, DEFAULT_XML_OPTIONS);
    out.close();
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  }

 }

}

使用当前的ApachePOI版本5.2.5.

结果:

enter image description here

Java相关问答推荐

Jooq隐式地将bigint转换为数字,并且索引不起作用

基于仅存在于父级中的字段查询子文档?

OpenJDK、4K显示和文本质量

如何在Java中声明未使用的变量?

ApachePOI:不带换行的新行

Java Swing:初始化身份验证类后未检测到ATM_Interface键事件

SpringBootreact 式Web应用程序的Spring Cloud Configer服务器中的资源控制器损坏

使用Testcontainers与OpenLiberty Server进行集成测试会抛出SocketException

如何获得执行人?

使用Mockito进行的Junit测试失败

使用GridBagLayout正确渲染

解释左移在Java中的工作原理

如何在JavaFX中处理多个按钮

为什么当我创建Robot对象时,JavaFX引发IlLegalStateException异常?

如何用内置Java从JavaFX应用程序中生成.exe文件?

在使用具有不同成本的谓词调用allMatch之前对Java流进行排序会带来什么好处吗?

为什么JavaFX MediaPlayer音频播放在Windows和Mac上运行良好,但在Linux(POPOS/Ubuntu)上却有问题?

H2数据库仅支持%1个结果集?

控制器建议异常处理

使用StringBuilder和append方法创建字符串时Java字符串内部方法的问题