Hammer Keyboard
Hammer Keyboard

Reputation: 55

Adding images and editing headers in .doc using java

I want to edit header of a .doc(word) document. Below code I have written :

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Section;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

public class WordReplaceText {
    public static final String SOURCE_FILE = "C:\\Users\\609650323\\Desktop\\Files\\Project\\GFAST\\surveyPack.doc";
    public static final String OUTPUT_FILE = "C:\\Users\\609650323\\Desktop\\Files\\Project\\GFAST\\surveyPack2.doc";

    public static void main(String[] args) throws Exception {
        WordReplaceText instance = new WordReplaceText();
        HWPFDocument doc = instance.openDocument(SOURCE_FILE);
        if (doc != null) {
            doc = instance.replaceText(doc,  "${A}", "AField");
            instance.saveDocument(doc, OUTPUT_FILE);

        }

    }

    private HWPFDocument replaceText(HWPFDocument doc, String findText, String replaceText) {
        Range r = doc.getRange();
        for (int i = 0; i < r.numSections(); ++i) {
            Section s = r.getSection(i);
            for (int j = 0; j < s.numParagraphs(); j++) {
                Paragraph p = s.getParagraph(j);
                for (int k = 0; k < p.numCharacterRuns(); k++) {
                    CharacterRun run = p.getCharacterRun(k);
                    String text = run.text();
                    if (text.contains(findText)) {
                        run.replaceText(findText, replaceText);
                    }
                }
            }
        }
        return doc;
    }

    private HWPFDocument openDocument(String file) throws Exception {
        URL res = getClass().getClassLoader().getResource(file);
        HWPFDocument document = null;
        if (res != null) {
            document = new HWPFDocument(new POIFSFileSystem(new File(res.getPath())));
        }else
            document = new HWPFDocument(new POIFSFileSystem(new File(SOURCE_FILE)));
        return document;
    }

    private void saveDocument(HWPFDocument doc, String file) {
        try {
            FileOutputStream out = new FileOutputStream(file);
            doc.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

But its not working, after executing below code, it is not able to open new document showing errors. Also I need to add pic in the box provided in the document. Does any body has any idea how to do that?

Below are the links I also tried :

Replacing variables in a word document template with java

Getting same error :

enter image description here

Upvotes: 0

Views: 1393

Answers (1)

Rainer Schwarze
Rainer Schwarze

Reputation: 4745

The short answer is likely and unfortunately: It does not work.

The long answer is:

HWPF is in an incomplete state and many things are not supported (the last time I looked maybe a year ago). The .doc file format is a complicated binary file format. Many tables exist with entries pointing to certain locations in the document. Changing one part of the document usually requires to update all the tables. There are tables for text runs, textboxes, bookmarks, shapes, tables (rows and columns) and many more. If you are lucky, you have a very simple document and most of the complicated tables are just not there. However, when you have shapes, images, textboxes etc. you likely run into things which are not yet / not properly supported in HWPF. The output is then usually an invalid Word file, which gets rejected by Word (if you're lucky) or it crashes Word more or less heavily (potentially up to needing a restart of the computer).

(I developed a custom HWPF library for a client which fixed all this some years ago. Hence I know the details.)

Alternatives

You may want to look at the .docx format instead of .doc. If you can arrange to get .docx files, you can use XWPF, which is in a much better state.

Regarding headers: As far as I remember, headers are not in the main document. You need to look at a headers sub document. (I believe it was XWPFHeader?)

Upvotes: 2

Related Questions