How to insert a paragraph by replacing a string in word document

Dhanu K :

I am using org.apache.poi poi-OOXML 3.17 in my java project. My requirement is to replace a text from a word document with some text(like a signature).

Somehow my code is adding that paragraph in the bottom of the page along with replacing my keyword, here is my block of code

public XWPFDocument addUserCompany(XWPFDocument doc, String imagePath,String userCompanyAddressInfo,String userCompanyContactInfo,String keyword) throws IOException, InvalidFormatException {
    int i=0;
    XWPFParagraph newPara = getNewPara(doc, imagePath, userCompanyAddressInfo, userCompanyContactInfo);
    for(XWPFParagraph existingPara:doc.getParagraphs()){
        for(XWPFRun existingRun:existingPara.getRuns()){
            if(existingRun!=null && existingRun.getText(0)!=null  && existingRun.getText(0).contains(keyword)){
                doc.setParagraph(newPara, i);
            }
        }
        i++;
    }
    return doc;
}
private XWPFParagraph getNewPara(XWPFDocument doc, String imagePath, String userCompanyAddressInfo, String userCompanyContactInfo) throws IOException, InvalidFormatException {
    XWPFParagraph newPara = doc.createParagraph();
    XWPFRun newRun = newPara.createRun();
    File imageFile1 = new File(imagePath);
    if (imageFile1.exists()) {
        int imgFormat1 = getImageFormat(imageFile1.getName());
        newRun.addPicture(new FileInputStream(imageFile1), imgFormat1, imageFile1.getName(), 491066, 491066);
        newRun.addBreak();
    }
    newRun.setText(userCompanyAddressInfo);
    newRun.addBreak();
    newRun.setText(userCompanyContactInfo);
    newRun.addBreak();
    return newPara;
}

word.addUserCompany(doc, userCompanyImage, userCompanyAddressInfo, userCompanyContactInfo, "${USERCONTACTINFO}");

here is my original document

enter image description here

and the screenshot of the result document is enter image description here

in the result document, you can see signature added in bottom page also along with top of the page

can someone help me fix this issue

Axel Richter :

Main problem is that XWPFDocument.createParagraph always appends a new paragraph to this document. So after setting that paragraph as replacement of the paragraph to replace by using XWPFDocument.setParagraph, we need removing the formerly created new paragraph from the document. For this XWPFDocument.removeBodyElement- can be used.

Btw.: You do not need the int i as position marker. There is XWPFDocument.getPosOfParagraph.

Since we need removing a paragraph from the document, this cannot be done in the loop over the paragraphs. So we need determining the paragraphToReplace in the loop first and then replacing that paragraph with the new created paragraph and then removing the new created paragraph from the document.

So the addUserCompany should be like:

 public XWPFDocument addUserCompany(XWPFDocument doc, String imagePath,String userCompanyAddressInfo,String 
  userCompanyContactInfo,String keyword) throws Exception {
  XWPFParagraph paragraphToReplace = null;
  for(XWPFParagraph existingPara : doc.getParagraphs()) {
   if(existingPara.getText().contains(keyword)) {
    paragraphToReplace = existingPara; 
   }
  }
  if (paragraphToReplace != null) {
   XWPFParagraph newPara = getNewPara(doc, imagePath, userCompanyAddressInfo, userCompanyContactInfo);
   doc.setParagraph(newPara, doc.getPosOfParagraph(paragraphToReplace));
   doc.removeBodyElement(doc.getPosOfParagraph(newPara));
  }
  return doc;
 }

Note that I do not try getting the placeholder from the text runs. Word sometimes uses strange rules for creating text runs. Thus in our example $ and { and USERCONTACTINFO and } might be each in it's own text run. Then existingRun.getText(0).contains(keyword) never would be true. However, since we are replacing the entire paragraph anyway, we can also check whether the paragraph contains the keyword using existingPara.getText().contains(keyword). This is true even if parts of the keyword are in separate text runs.

Complete example:

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

public class WordReplaceParagraphContainingKeyword {

 static XWPFDocument addUserCompany(XWPFDocument doc, String imagePath,String userCompanyAddressInfo,String 
  userCompanyContactInfo,String keyword) throws Exception {
  XWPFParagraph paragraphToReplace = null;
  for(XWPFParagraph existingPara : doc.getParagraphs()) {
   if(existingPara.getText().contains(keyword)) {
    paragraphToReplace = existingPara; 
   }
  }
  if (paragraphToReplace != null) {
   XWPFParagraph newPara = getNewPara(doc, imagePath, userCompanyAddressInfo, userCompanyContactInfo);
   doc.setParagraph(newPara, doc.getPosOfParagraph(paragraphToReplace));
   doc.removeBodyElement(doc.getPosOfParagraph(newPara));
  }
  return doc;
 }

 static XWPFParagraph getNewPara(XWPFDocument doc, String imagePath, String userCompanyAddressInfo, String 
  userCompanyContactInfo) throws Exception {
  XWPFParagraph newPara = doc.createParagraph();
  XWPFRun newRun = newPara.createRun();
  File imageFile1 = new File(imagePath);
  if (imageFile1.exists()) {
   //int imgFormat1 = getImageFormat(imageFile1.getName());
   int imgFormat1 = Document.PICTURE_TYPE_PNG;
   newRun.addPicture(new FileInputStream(imageFile1), imgFormat1, imageFile1.getName(), 491066, 491066);
   newRun.addBreak();
  }
  newRun.setText(userCompanyAddressInfo);
  newRun.addBreak();
  newRun.setText(userCompanyContactInfo);
  newRun.addBreak();
  return newPara;
 }

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

  XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));
  String userCompanyImage = "logo.png";
  String userCompanyAddressInfo = "111 E.Jefferson Avenue Naperville, Illinois 60540";
  String userCompanyContactInfo = "Phone: 312-100-7387";

  addUserCompany(doc, userCompanyImage, userCompanyAddressInfo, userCompanyContactInfo, "${USERCONTACTINFO}");

  FileOutputStream out = new FileOutputStream("result.docx");
  doc.write(out);
  out.close();
  doc.close();
 }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=34629&siteId=1
Recommended