1

我正在寻找可以读写 MS Word 文档的 java 库。我要做的是:

  • 读取模板文件,.dot 或 .doc,并用从 DB 读取的一些数据填充它
  • 从另一个 Word 文档中获取数据并将其与上述文件合并,保留段落格式

用户可以对文件进行更新。

我搜索并找到了 POI Apache 和 UNO OpenOffice。第一个可以轻松读取模板并用我自己的数据库数据替换任何占位符。我没有发现任何关于合并两个或更多文档的信息。OpenOffice UNO 看起来更稳定但也更复杂。此外,我不确定它是否具有合并文档的能力..

我们正在寻找正确的方向?

我认为的另一个解决方案是将 doc 文件转换为 docx。通过这种方式,我找到了更多可以帮助我们合并文档的库。但我该怎么做呢?

谢谢!

4

4 回答 4

1

您可以看看Docmosis,因为它提供了您提到的四个功能(数据填充、模板/文档合并、DOC 格式和 java 接口)。它有几种风格(下载、在线服务),但您可以注册免费试用云服务,看看 Docmosis 是否可以做您想做的事(然后您无需安装任何东西)或阅读在线文档。

它在后台使用 OpenOffice(您可以从开发人员指南安装说明中看到),它可以在文档之间进行相当不错的转换。UNO API 有一些复杂性——我建议使用 Docmosis 或 JODReports 直接将您的项目与 UNO 隔离开来。

希望有帮助。

于 2012-07-24T02:28:01.440 回答
1

我开发了下一个类(使用 Apache POI):

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;

public class WordMerge {

    private final OutputStream result;
    private final List<InputStream> inputs;
    private XWPFDocument first;

    public WordMerge(OutputStream result) {
        this.result = result;
        inputs = new ArrayList<>();
    }

    public void add(InputStream stream) throws Exception{            
        inputs.add(stream);
        OPCPackage srcPackage = OPCPackage.open(stream);
        XWPFDocument src1Document = new XWPFDocument(srcPackage);         
        if(inputs.size() == 1){
            first = src1Document;
        } else {            
            CTBody srcBody = src1Document.getDocument().getBody();
            first.getDocument().addNewBody().set(srcBody);            
        }        
    }

    public void doMerge() throws Exception{
        first.write(result);                
    }

    public void close() throws Exception{
        result.flush();
        result.close();
        for (InputStream input : inputs) {
            input.close();
        }
    }   
}

及其用途:

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

    FileOutputStream faos = new FileOutputStream("/home/victor/result.docx");

    WordMerge wm = new WordMerge(faos);

    wm.add( new FileInputStream("/home/victor/001.docx") );
    wm.add( new FileInputStream("/home/victor/002.docx") );

    wm.doMerge();
    wm.close();

}
于 2018-09-15T01:21:58.150 回答
1
import java.io.File;
import java.util.List;

import javax.xml.bind.JAXBException;

import org.docx4j.dml.CTBlip;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.ImageBmpPart;
import org.docx4j.openpackaging.parts.WordprocessingML.ImageEpsPart;
import org.docx4j.openpackaging.parts.WordprocessingML.ImageGifPart;
import org.docx4j.openpackaging.parts.WordprocessingML.ImageJpegPart;
import org.docx4j.openpackaging.parts.WordprocessingML.ImagePngPart;
import org.docx4j.openpackaging.parts.WordprocessingML.ImageTiffPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
import org.docx4j.openpackaging.parts.relationships.RelationshipsPart.AddPartBehaviour;
import org.docx4j.relationships.Relationship;

public class MultipleDocMerge {


    public static void main(String[] args) throws Docx4JException, JAXBException {
        File first = new File("D:\\Mreg.docx");
        File second = new File("D:\\Mreg1.docx");
        File third = new File("D:\\Mreg4&19.docx");
        File fourth = new File("D:\\test12.docx");   
        WordprocessingMLPackage f = WordprocessingMLPackage.load(first);
        WordprocessingMLPackage s = WordprocessingMLPackage.load(second);
        WordprocessingMLPackage a = WordprocessingMLPackage.load(third);
        WordprocessingMLPackage e = WordprocessingMLPackage.load(fourth);

        List body = s.getMainDocumentPart().getJAXBNodesViaXPath("//w:body", false);
        for(Object b : body){
            List filhos = ((org.docx4j.wml.Body)b).getContent();
            for(Object k : filhos)
                f.getMainDocumentPart().addObject(k);
        }

        List body1 = a.getMainDocumentPart().getJAXBNodesViaXPath("//w:body", false);
        for(Object b : body1){
            List filhos = ((org.docx4j.wml.Body)b).getContent();
            for(Object k : filhos)
                f.getMainDocumentPart().addObject(k);
        }

        List body2 = e.getMainDocumentPart().getJAXBNodesViaXPath("//w:body", false);
        for(Object b : body2){
            List filhos = ((org.docx4j.wml.Body)b).getContent();
            for(Object k : filhos)
                f.getMainDocumentPart().addObject(k);
        }


        List<Object> blips = e.getMainDocumentPart().getJAXBNodesViaXPath("//a:blip", false);
        for(Object el : blips){
            try {

                   CTBlip blip = (CTBlip) el;
                   RelationshipsPart parts = e.getMainDocumentPart().getRelationshipsPart();
                   Relationship rel = parts.getRelationshipByID(blip.getEmbed());
                   Part part = parts.getPart(rel);
                   if(part instanceof ImagePngPart)
                        System.out.println(((ImagePngPart) part).getBytes()); 
                   if(part instanceof ImageJpegPart)
                        System.out.println(((ImageJpegPart) part).getBytes()); 
                    if(part instanceof ImageBmpPart)
                        System.out.println(((ImageBmpPart) part).getBytes()); 
                    if(part instanceof ImageGifPart)
                        System.out.println(((ImageGifPart) part).getBytes()); 
                    if(part instanceof ImageEpsPart)
                        System.out.println(((ImageEpsPart) part).getBytes()); 
                    if(part instanceof ImageTiffPart)
                        System.out.println(((ImageTiffPart) part).getBytes()); 
                    Relationship newrel = f.getMainDocumentPart().addTargetPart(part,AddPartBehaviour.RENAME_IF_NAME_EXISTS);
                    blip.setEmbed(newrel.getId());
                    f.getMainDocumentPart().addTargetPart(e.getParts().getParts().get(new PartName("/word/"+rel.getTarget())));
                } catch (Exception ex){
                        ex.printStackTrace();
                } }

        File saved = new File("D:\\saved1.docx");
        f.save(saved);




    }

}
于 2018-02-15T05:24:06.830 回答
0

Apache POI 代码不适用于图像。

于 2020-01-22T12:33:07.830 回答