как добавить данные в файл DOCX с помощью DOCX4J - PullRequest
1 голос
/ 16 июня 2011

Скажите, пожалуйста, как добавить данные в файл docx, используя java и docx4j.

Что я делаю, так это то, что я использую шаблон в формате docx, в котором некоторые поля уклоняются Java во время выполнения,

Моя проблема заключается в том, что для каждой группы данных создается новый файл, и я просто хочу добавить новый файл в 1 файл. и это не делается с помощью потоков Java

String outputfilepath = "e:\\Practice/DOC/output/generatedLatterOUTPUT.docx";
String outputfilepath1 = "e:\\Practice/DOC/output/generatedLatterOUTPUT1.docx";
WordprocessingMLPackage wordMLPackage;

public void templetsubtitution(String name, String age, String gender, Document document)
        throws Exception {

    // input file name
    String inputfilepath = "e:\\Practice/DOC/profile.docx";
    // out put file name

    // id of Xml file
    String itemId1 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    String itemId2 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    String itemId3 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    // Load the Package

    if (inputfilepath.endsWith(".xml")) {

        JAXBContext jc = Context.jcXmlPackage;
        Unmarshaller u = jc.createUnmarshaller();
        u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());

        org.docx4j.xmlPackage.Package wmlPackageEl = (org.docx4j.xmlPackage.Package) ((JAXBElement) u
                .unmarshal(new javax.xml.transform.stream.StreamSource(
                        new FileInputStream(inputfilepath)))).getValue();

        org.docx4j.convert.in.FlatOpcXmlImporter xmlPackage = new org.docx4j.convert.in.FlatOpcXmlImporter(
                wmlPackageEl);

        wordMLPackage = (WordprocessingMLPackage) xmlPackage.get();

    } else {
        wordMLPackage = WordprocessingMLPackage
                .load(new File(inputfilepath));
    }

    CustomXmlDataStoragePart customXmlDataStoragePart = wordMLPackage
            .getCustomXmlDataStorageParts().get(itemId1);
    // Get the contents
    CustomXmlDataStorage customXmlDataStorage = customXmlDataStoragePart
            .getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:name[1]", name,
            "xmlns:ns0='EasyForm'");

    customXmlDataStoragePart = wordMLPackage.getCustomXmlDataStorageParts()
            .get(itemId2);
    // Get the contents
    customXmlDataStorage = customXmlDataStoragePart.getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:age[1]", age,
            "xmlns:ns0='EasyForm'");

    customXmlDataStoragePart = wordMLPackage.getCustomXmlDataStorageParts()
            .get(itemId3);
    // Get the contents
    customXmlDataStorage = customXmlDataStoragePart.getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:gender[1]", gender,
            "xmlns:ns0='EasyForm'");

    // Apply the bindings
    BindingHandler.applyBindings(wordMLPackage.getMainDocumentPart());
    File f = new File(outputfilepath);
    wordMLPackage.save(f);
    FileInputStream fis = new FileInputStream(f);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    try {
        for (int readNum; (readNum = fis.read(buf)) != -1;) {
            bos.write(buf, 0, readNum);
        }
        // System.out.println( buf.length);

    } catch (IOException ex) {
    }
    byte[] bytes = bos.toByteArray();
    FileOutputStream file = new FileOutputStream(outputfilepath1, true);
    DataOutputStream out = new DataOutputStream(file);
    out.write(bytes);
    out.flush();
    out.close();

    System.out.println("..done");
}

public static void main(String[] args) {
  utility u = new utility();
  u.templetsubtitution("aditya",24,mohan);
}

спасибо заранее

Ответы [ 2 ]

3 голосов
/ 23 мая 2013

Мне приходилось иметь дело с подобными вещами, и вот что я сделал (вероятно, не самый эффективный, но работающий):

  • создать finalDoc, загружающий шаблон и освобождающий его (поэтому у вас есть стили в этом документе)
  • для каждой строки данных, создайте новый документ, загружающий шаблон, затем замените ваши поля вашими значениями
  • используйте функцию ниже, чтобы добавить документ, заполненный данными, в finalDoc:

    public static void append(WordprocessingMLPackage docDest, WordprocessingMLPackage docSource) {
    List<Object> objects = docSource.getMainDocumentPart().getContent();
        for(Object o : objects){
            docDest.getMainDocumentPart().getContent().add(o);
        }
    }
    

Надеюсь, это поможет.

2 голосов
/ 23 августа 2013

Если я вас правильно понимаю, вы говорите о слиянии документов. Есть два очень простых подхода, которые вы можете использовать, и их эффективность действительно зависит от структуры и дальнейшего использования ваших данных:

  1. PhilippeAuriach описывает один подход в своем ответе, который влечет за собой добавление всех компонентов в экземпляре MaindocumentPart к другой. С точки зрения окончательного файла DOCX, это означает, что содержание который появляется в document.xml - он не будет учитывать заголовки и нижние колонтитулы (например), но это может быть хорошо для вас.

  2. Вы можете вставить несколько документов в один файл DOCX, вставив их как AltChunk элементы (см. документацию по docx4j). Это будет перенести все из одного файла Word в другой, заголовки и все. Недостатком этого является то, что ваш окончательный документ не будет надлежащим текущий файл Word, пока вы его не откроете и не сохраните в самом MS Word (импортированные компоненты остаются в виде отдельных файлов в docx расслоение). Это вызовет у вас проблемы, если вы хотите генерировать «объединить» файлы, а затем сделать что-то с ними, как рендеринга PDF объединенный контент будет просто игнорироваться.

Более полным (и сложным) подходом является выполнение «глубокого слияния». Это обновляет и поддерживает все ссылки, содержащиеся в документе. Импортированный контент становится частью основного «потока» документа (т. Е. Он не хранится как отдельные ссылки), поэтому конечным результатом является правильно слитый файл, который можно отобразить в PDF или как угодно.

Недостатком этого является то, что вам нужно хорошее знание структуры docx и API, и вы будете писать достаточно много кода (я бы рекомендовал вместо этого покупать лицензию на Plugext's MergeDocx ).

...