2016-01-30 44 views
2

我一直在嘗試使用Apache POI將.png圖像添加到.docx文件標題。我沒有找到幫助我的方法。有人知道它是怎麼做到的?通過這段代碼我可以只添加文本。使用POI將圖像添加到單詞.docx文檔標題XWPF

用於創建在標頭中 Word文件與頁眉和頁腳以及圖像
XWPFDocument docc = new XWPFDocument(); 
CTP ctpHeader = CTP.Factory.newInstance(); 
CTR ctrHeader = ctpHeader.addNewR(); 
CTText ctHeader = ctrHeader.addNewT(); 
String headerText = "mi encabezado"; 
ctHeader.setStringValue(headerText); 

XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, docc); XWPFParagraph[] parsHeader = new XWPFParagraph[1]; 
parsHeader[0] = headerParagraph; header.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader); 
+2

請顯示您嘗試的內容,並解釋「不工作」的含義。 –

+0

我曾嘗試使用此代碼,但沒有找到幫助我的方法。我只能添加文本 – MMora

+0

XWPFDocument docc = new XWPFDocument(); CTP ctpHeader = CTP.Factory.newInstance(); \t CTR ctrHeader = ctpHeader.addNewR(); \t \t \t CTText ctHeader = ctrHeader.addNewT(); \t \t \t String headerText =「mi encabezado」; \t \t \t ctHeader.setStringValue(headerText); \t \t \t \t \t \t \t \t \t XWPFParagraph headerParagraph =新XWPFParagraph(ctpHeader,DOCC); \t XWPFParagraph [] parsHeader = new XWPFParagraph [1]; \t parsHeader [0] = headerParagraph; \t header.createHeader(XWPFHeaderFooterPolicy.DEFAULT,parsHeader); – MMora

回答

8

實施例:

import java.io.FileOutputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 

import org.apache.poi.util.Units; 

import org.apache.poi.xwpf.usermodel.*; 

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc; 

import java.math.BigInteger; 

public class CreateWordHeaderFooter { 

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

    XWPFDocument doc= new XWPFDocument(); 

    // the body content 
    XWPFParagraph paragraph = doc.createParagraph(); 
    XWPFRun run=paragraph.createRun(); 
    run.setText("The Body:"); 

    paragraph = doc.createParagraph(); 
    run=paragraph.createRun(); 
    run.setText("Lorem ipsum...."); 

    // create header start 
    CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); 
    XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr); 

    XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = header.getParagraphArray(0); 
    paragraph.setAlignment(ParagraphAlignment.LEFT); 

    CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab(); 
    tabStop.setVal(STTabJc.RIGHT); 
    int twipsPerInch = 1440; 
    tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch)); 

    run = paragraph.createRun(); 
    run.setText("The Header:"); 
    run.addTab(); 

    run = paragraph.createRun(); 
    String imgFile="Koala.png"; 
    run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50)); 


    // create footer start 
    XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = footer.getParagraphArray(0); 
    paragraph.setAlignment(ParagraphAlignment.CENTER); 

    run = paragraph.createRun(); 
    run.setText("The Footer:"); 


    doc.write(new FileOutputStream("test.docx")); 

} 
} 

編輯2016年3月29日:

此工作過直到apache的POI 3.13。現在與3.14它沒有更多。原因:POI不會再爲頭段落中的圖片保存blip參考。

/word/header1.xml

代碼編譯和運行與3.13:

... 
<pic:blipFill><a:blip r:embed="rId1"/> 
... 

相同的代碼編譯和3.14運行:

... 
<pic:blipFill><a:blip r:embed=""/> 
... 

編輯2016年3月31日:

發現問題。有人認爲public final PackageRelationship getPackageRelationship()需要被棄用。因此,在XWPFRun.javapublic XWPFPicture addPicture(...)代碼改爲

從3.13版本:

... 
      CTBlipFillProperties blipFill = pic.addNewBlipFill(); 
      CTBlip blip = blipFill.addNewBlip(); 
      blip.setEmbed(picData.getPackageRelationship().getId()); 
... 

到3.14版本:

... 
      CTBlipFillProperties blipFill = pic.addNewBlipFill(); 
      CTBlip blip = blipFill.addNewBlip(); 
      blip.setEmbed(parent.getDocument().getRelationId(picData)); 
... 

parent.getDocument()XWPFDocument總是同時picData可能是關係到XWPFHeaderFooter

public XWPFPicture addPicture(...)的開頭,程序員已經知道這一點。

... 
     if (parent.getPart() instanceof XWPFHeaderFooter) { 
      XWPFHeaderFooter headerFooter = (XWPFHeaderFooter)parent.getPart(); 
      relationId = headerFooter.addPictureData(pictureData, pictureType); 
      picData = (XWPFPictureData) headerFooter.getRelationById(relationId); 
     } else { 
      XWPFDocument doc = parent.getDocument(); 
      relationId = doc.addPictureData(pictureData, pictureType); 
      picData = (XWPFPictureData) doc.getRelationById(relationId); 
     } 
... 

因此,如果貶值確實應該執行,這if..else也必須在設置blipID使用。但爲什麼折舊呢?

的Apache的POI 3.14版本

import java.io.FileOutputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 

import org.apache.poi.util.Units; 

import org.apache.poi.xwpf.usermodel.*; 

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc; 

import java.math.BigInteger; 

public class CreateWordHeaderFooter { 

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

    XWPFDocument doc= new XWPFDocument(); 

    // the body content 
    XWPFParagraph paragraph = doc.createParagraph(); 
    XWPFRun run=paragraph.createRun(); 
    run.setText("The Body:"); 

    paragraph = doc.createParagraph(); 
    run=paragraph.createRun(); 
    run.setText("Lorem ipsum...."); 

    // create header start 
    CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); 
    XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr); 

    XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = header.getParagraphArray(0); 
    paragraph.setAlignment(ParagraphAlignment.LEFT); 

    CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab(); 
    tabStop.setVal(STTabJc.RIGHT); 
    int twipsPerInch = 1440; 
    tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch)); 

    run = paragraph.createRun(); 
    run.setText("The Header:"); 
    run.addTab(); 

    run = paragraph.createRun(); 
    String imgFile="Koala.png"; 
    XWPFPicture picture = run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50)); 
    System.out.println(picture); //XWPFPicture is added 
    System.out.println(picture.getPictureData()); //but without access to XWPFPictureData (no blipID) 

    String blipID = ""; 
    for(XWPFPictureData picturedata : header.getAllPackagePictures()) { 
    blipID = header.getRelationId(picturedata); 
    System.out.println(blipID); //the XWPFPictureData are already there 
    } 
    picture.getCTPicture().getBlipFill().getBlip().setEmbed(blipID); //now they have a blipID also 
    System.out.println(picture.getPictureData()); 

    // create footer start 
    XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = footer.getParagraphArray(0); 
    paragraph.setAlignment(ParagraphAlignment.CENTER); 

    run = paragraph.createRun(); 
    run.setText("The Footer:"); 


    doc.write(new FileOutputStream("test.docx")); 

} 
} 

編輯2017年3月28日:

apache poi版3.16 Beta 2中,這似乎是固定的,因爲下面的代碼工作使用apache poi版本3.16 Beta 2:

import java.io.FileOutputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 

import org.apache.poi.util.Units; 

import org.apache.poi.xwpf.usermodel.*; 

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr; 

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop; 
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc; 

import java.math.BigInteger; 

public class CreateWordHeaderFooter2 { 

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

    XWPFDocument doc= new XWPFDocument(); 

    // the body content 
    XWPFParagraph paragraph = doc.createParagraph(); 
    XWPFRun run=paragraph.createRun(); 
    run.setText("The Body:"); 

    paragraph = doc.createParagraph(); 
    run=paragraph.createRun(); 
    run.setText("Lorem ipsum...."); 

    // create header start 
    CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr(); 
    XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr); 

    XWPFHeader header = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = header.createParagraph(); 
    paragraph.setAlignment(ParagraphAlignment.LEFT); 

    CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab(); 
    tabStop.setVal(STTabJc.RIGHT); 
    int twipsPerInch = 1440; 
    tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch)); 

    run = paragraph.createRun(); 
    run.setText("The Header:"); 
    run.addTab(); 

    run = paragraph.createRun(); 
    String imgFile="Koala.png"; 
    run.addPicture(new FileInputStream(imgFile), XWPFDocument.PICTURE_TYPE_PNG, imgFile, Units.toEMU(50), Units.toEMU(50)); 


    // create footer start 
    XWPFFooter footer = headerFooterPolicy.createFooter(XWPFHeaderFooterPolicy.DEFAULT); 

    paragraph = footer.createParagraph(); 
    paragraph.setAlignment(ParagraphAlignment.CENTER); 

    run = paragraph.createRun(); 
    run.setText("The Footer:"); 


    doc.write(new FileOutputStream("test.docx")); 

} 
} 
+0

由於您沒有檢查項目並且沒有在項目中進行單元測試來檢測破壞,所以使用低級別XML進行矇騙通常是一個風險選項。 「正確」的方式是爲項目貢獻一個補丁,以及一個單元測試,這將提供穩定的支持和對未來回歸的檢查。 – Gagravarr

+0

我在哪裏用低層XML在這裏做「Monkeying」?我以絕對正常的方式爲運行添加圖片。我期望這種方式的運行方式與文檔段落或標題段落相同。但事實並非如此。爲什麼?我真的應該回答這個嗎?或者項目程序員不應該回答這個問題嗎? –

+0

CT類是低級別的東西,可能會在將來的版本中被刪除(例如,從XMLBeans轉移到JAXP的版本)。如果您需要使用它們,理想情況下,您希望將它們包裝在一個不錯的用戶模型級別類中,併爲POI提供增強補丁以提供此補丁。 – Gagravarr

相關問題