2014-02-20 2 views
1

Сделано немного исследований по этому вопросу, и, похоже, в прошлом были ошибки, связанные с этим, я не уверен, что они решены в последней версии.Java Apache-POI XWPF как копировать или выводить растровые изображения?

Я читаю шаблон docx, делая несколько модов и выводя его. Я копирую все элементы документа отлично, за исключением растровых изображений, появляется маркер, где растровое изображение должно содержать текст, «это изображение в настоящее время не отображается». У меня было несколько таких дел.

Каков рекомендуемый способ копирования растрового изображения из одного документа в другой?

я могу получить изображения следующим образом:

Список piclist = template.getAllPictures();

XWPFPictureData picture = (XWPFPictureData) piclist.get (i);

Но я не уверен, как скопировать его в новый документ.

Я попытался тест добавление одного растрового изображения из файла и этот код создает документ Word, который дает ошибку и не загружается в Word:

InputStream рис = новый FileInputStream ("имя файла. GIF ");

outputDoc.addPictureData (pic, outputDoc.PICTURE_TYPE_GIF);

Любая помощь очень ценится. Очень впечатлен, как правило, Apache-POI.

+1

Это не совсем корректно, так как оно не связывает изображение нигде в документе. Что произойдет, если вы попробуете подход, показанный в [TestXWPFRun.testAddPicture()] (https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel /TestXWPFRun.java)? – Gagravarr

ответ

1

Довольно поздно ответ, но кто знает .. Если вы хотите скопировать фотографии одного документа к другому, попробуйте следующее:

public void copyAllImages(XWPFDocument sourceDocument, XWPFDocument targetDocument) { 
    Map<String, Integer> extractedImages = new HashMap<String, Integer>(); 
    XWPFPictureData pictureData = null; 

    // 1. Writing all found images to the disk (to the same folder as your source document) 
    for (XWPFParagraph par : sourceDocument.getParagraphs()) { 
     for (XWPFRun run : par.getRuns()) { 
      for (XWPFPicture picture : run.getEmbeddedPictures()) { 
       pictureData = picture.getPictureData(); 
       byte[] img = pictureData.getData(); 
       String fileName = pictureData.getFileName(); 
       int imageFormat = pictureData.getPictureType(); 
       writeByteArrayToFile(img, fileName); 
       extractedImages.put(fileName, imageFormat); 
      } 
     } 
    } 

    // 2. Writing images from the disk to the final document, 
    // creating 1 new paragraph with 1 run for each image. 
    for (String imageFileName : extractedImages.keySet()) { 
     XWPFParagraph newParagraph = targetDocument.createParagraph(); 
     XWPFRun newRun = newParagraph.createRun(); 
     copyImageToRun(imageFileName, newRun, extractedImages.get(imageFileName)); 
    } 
} 

private static void writeByteArrayToFile(byte[] byteArray, String fileName) { 
    FileOutputStream out = null; 
    try { 
     out = new FileOutputStream(new File(fileName)); 
     out.write(byteArray); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      out.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private void copyImageToRun(String imageFileName, XWPFRun run, int format) { 
    run.setText(imageFileName); 
    run.addBreak(); 

    try { 
     run.addPicture(new FileInputStream(imageFileName), format, imageFileName, 
       Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    run.addBreak(BreakType.PAGE); 
} 

Таким образом, вы только два XWPFDocument объекты, передать их в первой функции (copyAllImages), а затем сохраните эти документы, используя, как обычно, document.write(out). В зависимости от ваших потребностей вы также можете добавить к шагу 1 код, который скопирует все содержимое ваших абзацев (а не только изображений). Вероятно, можно пропустить запись образов на диск, вставив эту pictureData непосредственно во вновь созданный прогон. Однако мне не удалось заставить его работать (изображения просто не появлялись). Но, используя двухэтапный подход, он, наконец, дал результат.

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

P.S. теперь вопрос заключается в том, какой размер изображения использовать? На мгновение я видел только ту функцию addPicture, которая обязывает вас пропускать ширину и высоту, что также может перемасштабировать ваше изображение. Таким образом, нам нужен какой-то трюк, чтобы извлечь размер (в пикселях), который каждое изображение взяло в исходном документе (а не в оригинальном размере оригинала, поскольку он может быть изменен пользователем).

Вдохновленный от here.

Смежные вопросы