Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
489 views
in Technique[技术] by (71.8m points)

io - How to edit MS Word documents using Java?

I do have few Word templates, and my requirement is to replace some of the words/place holders in the document based on the user input, using Java. I tried lot of libraries including 2-3 versions of docx4j but nothing work well, they all just didn't do anything!

I know this question has been asked before, but I tried all options I know. So, using what java library I can "really" replace/edit these templates? My preference goes to the "easy to use / Few line of codes" type libraries.

I am using Java 8 and my MS Word templates are in MS Word 2007.

Update

This code is written by using the code sample provided by SO member Joop Eggen

public Main() throws URISyntaxException, IOException, ParserConfigurationException, SAXException
    {
        URI docxUri = new URI("C:/Users/Yohan/Desktop/yohan.docx");
        Map<String, String> zipProperties = new HashMap<>();
        zipProperties.put("encoding", "UTF-8");

         FileSystem zipFS = FileSystems.newFileSystem(docxUri, zipProperties);

           Path documentXmlPath = zipFS.getPath("/word/document.xml");

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();

            Document doc = builder.parse(Files.newInputStream(documentXmlPath));

            byte[] content = Files.readAllBytes(documentXmlPath);
            String xml = new String(content, StandardCharsets.UTF_8);
            //xml = xml.replace("#DATE#", "2014-09-24");
            xml = xml.replace("#NAME#", StringEscapeUtils.escapeXml("Sniper"));

            content = xml.getBytes(StandardCharsets.UTF_8);
            Files.write(documentXmlPath, content);
    }

However this returns the below error

java.nio.file.ProviderNotFoundException: Provider "C" Not found

at: java.nio.file.FileSystems.newFileSystem(FileSystems.java:341) at java.nio.file.FileSystems.newFileSystem(FileSystems.java:341)

at java.nio.fileFileSystems.newFileSystem(FileSystems.java:276)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

One may use for docx (a zip with XML and other files) a java zip file system and XML or text processing.

URI docxUri = ,,, // "jar:file:/C:/... .docx"
Map<String, String> zipProperties = new HashMap<>();
zipProperties.put("encoding", "UTF-8");
try (FileSystem zipFS = FileSystems.newFileSystem(docxUri, zipProperties)) {
    Path documentXmlPath = zipFS.getPath("/word/document.xml");

When using XML:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();

    Document doc = builder.parse(Files.newInputStream(documentXmlPath));
    //Element root = doc.getDocumentElement();

You can then use XPath to find the places, and write the XML back again.

It even might be that you do not need XML but could replace place holders:

    byte[] content = Files.readAllBytes(documentXmlPath);
    String xml = new String(content, StandardCharsets.UTF_8);
    xml = xml.replace("#DATE#", "2014-09-24");
    xml = xml.replace("#NAME#", StringEscapeUtils.escapeXml("Sniper")));
    ...
    content = xml.getBytes(StandardCharsets.UTF_8);
    Files.delete(documentXmlPath);
    Files.write(documentXmlPath, content);

For a fast development, rename a copy of the .docx to a name with the .zip file extension, and inspect the files.

File.write should already apply StandardOpenOption.TRUNCATE_EXISTING, but I have added Files.delete as some error occured. See comments.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...