Add image into a word .docx document header using POI XWPF - java

I've been trying to add .png image to .docx file header with Apache POI. I did´t find a method that help me. someone know how do it?
Whith this code I could add only text.
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);

Example for creating a Word document with header and footer and an image in the header:
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"));
}
}
Edit Mar 29 2016:
This had worked until apache poi 3.13. Now with 3.14 it works not more. Reason: POI will not save the blip reference for images in header paragraphs anymore.
/word/header1.xml:
Code compiled and run with 3.13:
...
<pic:blipFill><a:blip r:embed="rId1"/>
...
Same code compiled and run with 3.14:
...
<pic:blipFill><a:blip r:embed=""/>
...
Edit Mar 31 2016:
Found the problem. Someone was the opinion the public final PackageRelationship getPackageRelationship() needs to be deprecated. So in XWPFRun.java the code in public XWPFPicture addPicture(...) was changed
from version 3.13:
...
CTBlipFillProperties blipFill = pic.addNewBlipFill();
CTBlip blip = blipFill.addNewBlip();
blip.setEmbed(picData.getPackageRelationship().getId());
...
to version 3.14:
...
CTBlipFillProperties blipFill = pic.addNewBlipFill();
CTBlip blip = blipFill.addNewBlip();
blip.setEmbed(parent.getDocument().getRelationId(picData));
...
But parent.getDocument() is the XWPFDocument always while the picData possible is related to the XWPFHeaderFooter.
At the beginning of the public XWPFPicture addPicture(...) the programmers have already know this.
...
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);
}
...
So if the depreciation should really be enforced, this if..else must also be used while setting the blipID. But why the depreciation at all?
The apache poi 3.14 version lol
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"));
}
}
Edit Mar 28 2017:
In apache poi version 3.16 Beta 2 this seems to be fixed since the following code works using apache poi version 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"));
}
}

Related

PDFBox Customized PDFTextStripper

I'm a rookie, really. I'm building my first project (if I can finish it).
I want to extract PDF text with formatting and location, and then write to .docx file. I checked the PDFBox API documentation, but I'm not sure if I want to get the location of the text, then should I traverse the rows? Or traverse the characters? I studied these three carefully.
Text coordinates when stripping from PDFBox
Get font of each line using PDFBox
How to extract font styles of text contents using pdfbox?
And here is my DEMO:
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import java.io.IOException;
import java.util.List;
public class PDFTextExtractor extends PDFTextStripper {
/**
* Instantiate a new PDFTextStripper object.
*
* #throws IOException If there is an error loading the properties.
*/
public PDFTextExtractor() throws IOException {
}
String prevFont = "";
#Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
StringBuilder sb = new StringBuilder();
for (TextPosition position : textPositions){
String font = position.getFont().getName();
float x = position.getX();
float y = position.getY();
float fontSize = position.getFontSizeInPt();
if (font != null && !font.equals(prevFont)){
sb.append("[").append(font.split("-")[0]).append("+").append(font.split("-")[1]).append("+").append(fontSize).append("]");
prevFont = font;
}
sb.append(position.getUnicode());
}
writeString(sb.toString());
}
#Override
public String getText(PDDocument doc) throws IOException {
return super.getText(doc);
}
}
And i calling it like here:
FileOutputStream outputStream = new FileOutputStream(EXPORT_PATH + file.getName().split("\\.")[0] + ".docx");
try (PDDocument originalPDF = PDDocument.load(file);
XWPFDocument doc = new XWPFDocument()) {
//get All pages
PDPageTree pageList = originalPDF.getDocumentCatalog().getPages();
for (PDPage page : pageList){
//Parse Content
PDFTextStripper stripper = new PDFTextExtractor();
stripper.setSortByPosition(true);
String ss = stripper.getText(originalPDF);
System.out.println(ss);
//Write Content
XWPFParagraph paragraph = doc.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(ss);
run.addBreak(BreakType.PAGE);
}
doc.write(outputStream);
originalPDF.close();
outputStream.close();
}

How to add a hyperlink to the footer of a XWPFDocument using Apache POI?

The appendExternalHyperlink() method (source) is not working in the footer of a XWPFDocument. In the footer the result is not getting recognised as a hyperlink.
I am new to Apache POI and have no experiences with the low level stuff. Can someone explain what is the problem in here, please?
public class FooterProblem {
public static void main(final String[] args) throws Exception {
final XWPFDocument docx = new XWPFDocument();
final XWPFParagraph para = docx.createParagraph();
final XWPFRun paraRun = para.createRun();
paraRun.setText("Email: ");
appendExternalHyperlink("mailto:me#example.com", "me#example.com", para);
final XWPFParagraph footer = docx.createFooter(HeaderFooterType.DEFAULT).createParagraph();
final XWPFRun footerRun = footer.createRun();
footerRun.setText("Email: ");
appendExternalHyperlink("mailto:me#example.com", "me#example.com", footer);
final FileOutputStream out = new FileOutputStream("FooterProblem.docx");
docx.write(out);
out.close();
docx.close();
}
public static void appendExternalHyperlink(final String url, final String text, final XWPFParagraph paragraph) {
// Add the link as External relationship
final String id = paragraph.getDocument().getPackagePart()
.addExternalRelationship(url, XWPFRelation.HYPERLINK.getRelation()).getId();
// Append the link and bind it to the relationship
final CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();
cLink.setId(id);
// Create the linked text
final CTText ctText = CTText.Factory.newInstance();
ctText.setStringValue(text);
final CTR ctr = CTR.Factory.newInstance();
ctr.setTArray(new CTText[] { ctText });
// Insert the linked text into the link
cLink.setRArray(new CTR[] { ctr });
}
}
The footer[n].xml is its own package part and needs its own relations. But your code creates the external hyperlink relations for the document.xml package part always. It always uses paragraph.getDocument(). This is wrong.
The following code provides a method for creating a XWPFHyperlinkRun in a given XWPFParagraph and gets the correct package part to put the relations on. It uses paragraph.getPart() to get the correct part. So this method works for paragraphs in the document body as well as in header and/or footer.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
public class CreateWordHyperlinks {
static XWPFHyperlinkRun createHyperlinkRun(XWPFParagraph paragraph, String uri) throws Exception {
String rId = paragraph.getPart().getPackagePart().addExternalRelationship(
uri,
XWPFRelation.HYPERLINK.getRelation()
).getId();
CTHyperlink cthyperLink=paragraph.getCTP().addNewHyperlink();
cthyperLink.setId(rId);
cthyperLink.addNewR();
return new XWPFHyperlinkRun(
cthyperLink,
cthyperLink.getRArray(0),
paragraph
);
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("This is a text paragraph having a link to Google ");
XWPFHyperlinkRun hyperlinkrun = createHyperlinkRun(paragraph, "https://www.google.de");
hyperlinkrun.setText("https://www.google.de");
hyperlinkrun.setColor("0000FF");
hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE);
run = paragraph.createRun();
run.setText(" in it.");
XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);
paragraph = footer.createParagraph();
run = paragraph.createRun();
run.setText("Email: ");
hyperlinkrun = createHyperlinkRun(paragraph, "mailto:me#example.com");
hyperlinkrun.setText("me#example.com");
hyperlinkrun.setColor("0000FF");
hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE);
FileOutputStream out = new FileOutputStream("CreateWordHyperlinks.docx");
document.write(out);
out.close();
document.close();
}
}

Apache POI and XDOCREPORT NullPointerException

I am doing a placeholder replacements in docx file and after that I need to convert file to PDF. All of my efforts are ending in
fr.opensagres.poi.xwpf.converter.core.XWPFConverterException: java.lang.NullPointerException
at fr.opensagres.poi.xwpf.converter.pdf.PdfConverter.doConvert(PdfConverter.java:71)
at fr.opensagres.poi.xwpf.converter.pdf.PdfConverter.doConvert(PdfConverter.java:39)
at fr.opensagres.poi.xwpf.converter.core.AbstractXWPFConverter.convert(AbstractXWPFConverter.java:46).
I am using these dependencies:
implementation("org.apache.poi:poi-ooxml:3.17")
implementation("fr.opensagres.xdocreport:fr.opensagres.xdocreport.converter.docx.xwpf:2.0.1")
If I try to convert source (unchanged) docx file, everything works as it should, but when I do replace placeholders and save document, everything crashes.
Piece of my code:
FileInputStream fis = new FileInputStream(COPIED);
XWPFDocument doc = new XWPFDocument(fis);
doc.createStyles();
for (XWPFParagraph p : doc.getParagraphs()) {
List<XWPFRun> runs = p.getRuns();
if (runs != null) {
for (XWPFRun r : runs) {
String text = r.getText(0);
StringSubstitutor substitutor = new StringSubstitutor(fieldsForReport);
String replacedText = substitutor.replace(text);
r.setText(replacedText, 0);
}
}
}
for (XWPFTable tbl : doc.getTables()) {
for (XWPFTableRow row : tbl.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph p : cell.getParagraphs()) {
for (XWPFRun r : p.getRuns()) {
String text = r.getText(0);
StringSubstitutor substitutor = new StringSubstitutor(fieldsForReport);
String replacedText = substitutor.replace(text);
r.setText(replacedText, 0);
}
}
}
}
}
FileOutputStream fos = new FileOutputStream(COPIED);
doc.write(fos);
doc.close();
FileInputStream fis = new FileInputStream(COPIED);
XWPFDocument document = new XWPFDocument(fis);
PdfOptions options = PdfOptions.create();
PdfConverter converter = (PdfConverter) PdfConverter.getInstance();
converter.convert(document, new FileOutputStream(DEST), options);
document.close();
The following works for me using the newest apache poi version 4.0.1 and the newest version 2.0.2 of fr.opensagres.poi.xwpf.converter.core and consorts.
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.File;
//needed jars: fr.opensagres.poi.xwpf.converter.core-2.0.2.jar,
// fr.opensagres.poi.xwpf.converter.pdf-2.0.2.jar,
// fr.opensagres.xdocreport.itext.extension-2.0.2.jar,
// itext-4.2.1.jar
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
//needed jars: apache poi and it's dependencies
//inclusive ooxml-schemas-1.4.jar
import org.apache.poi.xwpf.usermodel.*;
public class DOCXToPDFConverterSampleMin {
public static void main(String[] args) throws Exception {
String docPath = "./WordDocument.docx";
String pdfPath = "./WordDocument.pdf";
InputStream in = new FileInputStream(new File(docPath));
XWPFDocument document = new XWPFDocument(in);
for (XWPFParagraph paragraph : document.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if (text != null && text.contains("$name$")) {
text = text.replace("$name$", "Axel Richter");
run.setText(text, 0);
} else if (text != null && text.contains("$date$")) {
text = text.replace("$date$", "2019-02-28");
run.setText(text, 0);
}
}
}
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if (text != null && text.contains("$name$")) {
text = text.replace("$name$", "Axel Richter");
run.setText(text,0);
} else if (text != null && text.contains("$date$")) {
text = text.replace("$date$", "2019-02-28");
run.setText(text, 0);
}
}
}
}
}
}
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("This is new Text in this document.");
PdfOptions options = PdfOptions.create();
OutputStream out = new FileOutputStream(new File(pdfPath));
PdfConverter.getInstance().convert(document, out, options);
document.close();
out.close();
}
}

Is iText7 possible to display fonts with IVS(Ideographic Variation Sequence)?

I am using the iText7(v7.1.1) to create PDF-file.
Environment: java version "1.7.0_45".
For IVS(Ideographic Variation Sequence) see below
http://blogs.adobe.com/CCJKType/files/2017/09/iuc32-lunde-s5t3.pdf
Sample-Code see below
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.io.font.PdfEncodings;
import java.io.File;
public class SimpleTableIVS {
public static final String DEST = "SimpleTableIVS.pdf";
public static void main(String[] args) throws Exception {
File file = new File(DEST);
new SimpleTableIVS().manipulatePdf(DEST);
}
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);
// UTF-8 encoding table and Unicode characters
// http://www.utf8-chartable.com/unicode-utf8-table.pl?start=131072&unicodeinhtml=hex&htmlent=1
// http://www.utf8-chartable.com/unicode-utf8-table.pl?start=33792&number=1024
byte[] bUtfA = {(byte)0xd8, (byte)0x40, (byte)0xdc, (byte)0x0b}; // U+2000B [IVS:2000B_E0103]
byte[] bUtfB = {(byte)0x84, (byte)0x5b}; // U+845B, [IVS: 845B_E0103]
// After Add "Ideographic Variation Selector"
byte[] bUtfC = {(byte)0xdb, (byte)0x40, (byte)0xdd, (byte)0x01}; // U+E0101
byte[] bUtfD = {(byte)0xdb, (byte)0x40, (byte)0xdd, (byte)0x02}; // U+E0102
//PdfFont font = PdfFontFactory.createFont("C:/Windows/Fonts/msmincho.ttc,0", PdfEncodings.IDENTITY_H);
//PdfFont font = PdfFontFactory.createFont("C:/Windows/Fonts/meiryo.ttc,0", PdfEncodings.IDENTITY_H);
PdfFont font = PdfFontFactory.createFont("C:/Program Files/ipamjm/ipamjm.ttf", PdfEncodings.IDENTITY_H);
String strUtfA = new String(bUtfA, "UTF-16");
String strUtfB = new String(bUtfB, "UTF-16");
String strUtfC = strUtfA + (new String(bUtfC, "UTF-16"));
String strUtfD = strUtfB + (new String(bUtfD, "UTF-16"));
Table table = new Table(4);
table.addCell(new Paragraph("\u200d" + strUtfA).setFont(font).setFontSize(12));
table.addCell(new Paragraph("\u200d" + strUtfB).setFont(font).setFontSize(12));
table.addCell(new Paragraph("\u200d" + strUtfC).setFont(font).setFontSize(12));
table.addCell(new Paragraph("\u200d" + strUtfD).setFont(font).setFontSize(12));
doc.add(table);
doc.close();
}
}
Unfortunately, Ideographic Variation Sequences are not currently supported in iText. Supporting it is feasible, but not very easy, and thus is not the highest priority at the moment.
An internal development ticket has been created for that and it would be great to implement this feature in the next versions.

java poi XWPF word - create bookmark in new document

Very many examples exist for reading and editing/replacing bookmarks in XWPF word document.
But I want to create a document and create new bookmarks.
Create document - no problem:
private void createWordDoc() throws IOException {
XWPFDocument document = new XWPFDocument();
File tempDocFile = new File(pathName+"\\temp.docx");
FileOutputStream out = new FileOutputStream(tempDocFile);
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("testing string ");
document.write(out);
out.close();
}
How can I make a bookmark on text "testing string"?
This is not implemented in high level classes of apache poi until now. Therefore low level CTP and CTBookmark are needed.
Example:
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import java.math.BigInteger;
public class CreateWordBookmark {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
//bookmark before the run
CTBookmark bookmark = paragraph.getCTP().addNewBookmarkStart();
bookmark.setName("before_testing_string");
bookmark.setId(BigInteger.valueOf(0));
paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(0));
//bookmark the run
bookmark = paragraph.getCTP().addNewBookmarkStart();
bookmark.setName("testing_string");
bookmark.setId(BigInteger.valueOf(1));
XWPFRun run = paragraph.createRun();
run.setText("testing string ");
paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(1));
//bookmark after the run
bookmark = paragraph.getCTP().addNewBookmarkStart();
bookmark.setName("after_testing_string");
bookmark.setId(BigInteger.valueOf(2));
paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(2));
document.write(new FileOutputStream("CreateWordBookmark.docx"));
document.close();
}
}

Categories

Resources