0

I need to open a .dotx document, modify the content (or something similar) and put my own data, and then return generated .docx/document.

for exemple in the dotx file, the string "name" should be replaced by "John" in genrated docx file.

public static void main( String[] args ) throws IOException
{
    String inputFile="D:/Copies 2.dotx";
//  String outputeFile="D:/test.txt";
    String outputeFile="D:/test.docx";
    File inFile=new File(inputFile);
    File ouFile=new File(outputeFile);
    Map<String,String> hm = new HashMap<String,String>();
    hm.put("Namur","Youssef");
    App a = new App();
    a.changeData(inFile,ouFile, hm);    
}
private void changeData(File targetFile,File out, Map<String,String> substitutionData) throws IOException{
    BufferedReader br = null;
    String docxTemplate = "";
    try {
        br = new BufferedReader(new InputStreamReader(new FileInputStream(targetFile)));
        String temp;
        while( (temp = br.readLine()) != null) {
            docxTemplate = docxTemplate + temp;   
        }
        br.close();
    } 
    catch (IOException e) {
        br.close();
        throw e;
    }

    Iterator<Entry<String, String>> substitutionDataIterator = substitutionData.entrySet().iterator();
    while(substitutionDataIterator.hasNext()){
        Map.Entry<String,String> pair = (Map.Entry<String,String>)substitutionDataIterator.next();
        if(docxTemplate.contains(pair.getKey())){
            if(pair.getValue() != null)
                docxTemplate = docxTemplate.replace(pair.getKey(), pair.getValue());
            else
                docxTemplate = docxTemplate.replace(pair.getKey(), "NEDOSTAJE");
        }
    }

    FileOutputStream fos = null;
    try{
        fos = new FileOutputStream(out);
        fos.write(docxTemplate.getBytes());
        fos.close();
    }
    catch (IOException e) {
        fos.close();
        throw e;
    }

}

Can someone give me some advice on this?

Ps: i'm using apach POI 3.16

5
  • 1
    Where do you think you are using any apache poi classes in your current code? Commented Feb 8, 2019 at 11:26
  • yes indeed in this code i didn't use apache POI , it's run and compile correctly but the output file give me this error when i try to open it "we are sorry we couldn't open your test1 because we found a problem with content " and i'm wondering if there is a way to Replacing content in a word template document with java using POI . Commented Feb 8, 2019 at 11:58
  • First thing to know: What is a *.dotx file? Is it simply a text file? No, it is a file in Office Open XML format which is a ZIP archive containing a special directory structure having different other files (mainly XML files) stored in. So you cannot simply handle it like a text file then. That's what apache poi is made for. Commented Feb 8, 2019 at 12:09
  • Second thing to know: What is the difference between a *.dotx and a *.docx file? It mainly is the content-type. So while read *.dotx and then save *.docx you also needs changing the content-type settings within the file. See stackoverflow.com/questions/54377200/…. Commented Feb 8, 2019 at 12:09
  • @AxelRichter Thank a lot , i think you're right I should convert it first ! Commented Feb 8, 2019 at 12:18

1 Answer 1

2

As it is not as simple to parse a dotx/docx file We have apache poi doing this with some effort like

XWPFDocument doc = new XWPFDocument(OPCPackage.open("-you docx/dotx file-path-"));

With this you can load an existing file. Now to parse over file you get

XWPFParagraph
XWPFTable

You can parse over both like this

for (XWPFParagraph p : doc.getParagraphs()) {
                List<XWPFRun> runs = p.getRuns();
                if (runs != null) {
                    for (XWPFRun r : runs) {
                        String text = r.getText(0);
                        if (text != null && text.contains("$$key$$")) {
                            text = text.replace("<asdas>", "ABCD");// your content
                            r.setText(text, 0);
                        }
                    }
                }
            }

To parse over table

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);
                                if (text != null && text.contains("$$key$$")) {
                                    text = text.replace("<asdas>", "abcd");
                                    r.setText(text, 0);
                                }
                            }
                        }
                    }
                }
            }

Now to write the the parsed file in a target you get

doc.write(new FileOutputStream("-taget-path-"));

This needs all dependencies with apache POI like

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

You will need some more into your build path check your exceptions and add.

You can use this link and explore more

http://poi.apache.org/apidocs/dev/org/apache/poi/xwpf/usermodel/XWPFRun.html#setText%28java.lang.String%29

Sign up to request clarification or add additional context in comments.

5 Comments

I just tried this code, but when i open the output file i get this error " we are sorry we couldn't open your test1 because we found a problem with content "
Check the file content first then check what you are writting you should read docx/dotx and write it as docx
@Kishan C S: You cannot read *.dotx and write that as *.docx without changing [Content_Types].xml. Libreoffice or OpenOffice Writer will tolerate wrong content-types but Microsoft Word will not.
Then he has to update the content.xml by opening the file.Thank you Axel Richter
Yes indeed, i should Check the file content first, thank you @KishanCS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.