2016-06-02 7 views
0

Мне нужно заменить управление контентом изображения на изображение. Код работает нормально, но когда Слово пытается открыть файл, он сообщает Catastophic недостаточности:Замененный контроль содержимого изображения с изображением - Отчет о словах Катастрофический сбой при открытии файла

enter image description here

Кодекса в основном регулируются версией ImageAdd класса из образцов docx4j. Смешно, что документ, преобразованный в PDF, отображает ОК.

List<SdtElement> contentControls = findContentControls(wordMLPackage.getMainDocumentPart(InputStream)); 

for (SdtElement contentControl : contentControls) { 
    for (Object ob : contentControl.getSdtContent().getContent()) { 
     traverseEelements(ob, value); 
    } 
} 

static List<SdtElement> findContentControls(ContentAccessor container) throws Docx4JException, JAXBException { 
    List<SdtElement> sdtElements = new LinkedList<SdtElement>(); 
    for (Object o : container.getContent()) { 
     Object unwrapped = XmlUtils.unwrap(o); 
     if (unwrapped instanceof SdtElement) { 
      sdtElements.add((SdtElement) unwrapped); 
     } 
     if (unwrapped instanceof ContentAccessor) { 
      List<SdtElement> list = findContentControls((ContentAccessor) unwrapped); 
      sdtElements.addAll(list); 
     } 
    } 
    return sdtElements; 
} 

private void traverseEelements(Object object, String value) { 
    if (object instanceof org.docx4j.wml.Text) { 
     Text text = (org.docx4j.wml.Text) object; 
     text.setValue(value); 
    } else if (object instanceof ContentAccessor) { 
     ContentAccessor contentAccessor = (ContentAccessor) object; 
     for (Object ob : contentAccessor.getContent()) { 
      traverseEelements(ob, value); 
     } 
    } else if (object instanceof JAXBElement) { 
     Object v = ((JAXBElement<?>) object).getValue(); 
     if (v instanceof ContentAccessor) { 
      ContentAccessor contentAccessor = (ContentAccessor) v; 
      for (Object ob : contentAccessor.getContent()) { 
       traverseEelements(ob, value); 
      } 
     } else if (v instanceof org.docx4j.wml.Text) { 
      Text text = (org.docx4j.wml.Text) v; 
      text.setValue(value); 
     } else if (v instanceof org.docx4j.wml.Drawing) { 
      Drawing drawing = (Drawing) v; 
      try { 
       File file = new File("C://Users//user//Pictures//test.png"); 
       java.io.InputStream is = new java.io.FileInputStream(file); 
       long length = file.length(); 
       if (length > Integer.MAX_VALUE) { 
        System.out.println("File too large!!"); 
       } 
       byte[] bytes = new byte[(int)length]; 
       int offset = 0; 
       int numRead = 0; 
       while (offset < bytes.length 
         && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { 
        offset += numRead; 
       } 
       // Ensure all the bytes have been read in 
       if (offset < bytes.length) { 
        System.out.println("Could not completely read file "+file.getName()); 
       } 
       is.close(); 
       String filenameHint = null; 
       String altText = null; 
       int id1 = 0; 
       int id2 = 1; 
       BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); 
       Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false); 
       drawing.getAnchorOrInline().add(inline); 
      } catch(Exception e) { 
       logger.error(e); 
      } 
     } else { 
      logger.error("unspupported element found: " + object.getClass()); 
     } 
    } else { 
     logger.error("unspupported element found: " + object.getClass()); 
    } 
} 

EDIT

Link to the file

+0

Загрузить docx где-нибудь? – JasonPlutext

+0

Привет, Джейсон, я ожидал тебя :) Я добавил ссылку на файл в конце вопроса – Miki

ответ

1

У вас есть W: рисунок, содержащий как РГ: якорь, и РГ: встроенный:

 <w:drawing> 
      <wp:anchor distT="0" distB="0" distL="114300" distR="114300" simplePos="false" relativeHeight="251658240" behindDoc="true" locked="false" layoutInCell="true" allowOverlap="true"> 
      <wp:simplePos x="0" y="0"/> 
      <wp:positionH relativeFrom="column"> 
       <wp:posOffset>0</wp:posOffset> 
      </wp:positionH> 
      <wp:positionV relativeFrom="paragraph"> 
       <wp:posOffset>0</wp:posOffset> 
      </wp:positionV> 
      <wp:extent cx="18288" cy="18288"/> 
      <wp:effectExtent l="0" t="0" r="0" b="0"/> 
      <wp:wrapNone/> 
      <wp:docPr id="1" name="Picture 1"/> 
      <wp:cNvGraphicFramePr> 
       <a:graphicFrameLocks noChangeAspect="true"/> 
      </wp:cNvGraphicFramePr> 
      <a:graphic> 
       <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"> 
       <pic:pic> 
        <pic:nvPicPr> 
        <pic:cNvPr id="0" name="Picture 1"/> 
        <pic:cNvPicPr> 
         <a:picLocks noChangeAspect="true" noChangeArrowheads="true"/> 
        </pic:cNvPicPr> 
        </pic:nvPicPr> 
        <pic:blipFill> 
        <a:blip cstate="print" r:embed="rId4"> 
         <a:extLst> 
         <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}"> 
          <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" val="0"/> 
         </a:ext> 
         </a:extLst> 
        </a:blip> 
        <a:srcRect/> 
        <a:stretch> 
         <a:fillRect/> 
        </a:stretch> 
        </pic:blipFill> 
        <pic:spPr bwMode="auto"> 
        <a:xfrm> 
         <a:off x="0" y="0"/> 
         <a:ext cx="18288" cy="18288"/> 
        </a:xfrm> 
        <a:prstGeom prst="rect"> 
         <a:avLst/> 
        </a:prstGeom> 
        <a:noFill/> 
        <a:ln> 
         <a:noFill/> 
        </a:ln> 
        </pic:spPr> 
       </pic:pic> 
       </a:graphicData> 
      </a:graphic> 
      </wp:anchor> 
      <wp:inline distT="0" distB="0" distL="0" distR="0"> 
      <wp:extent cx="952500" cy="333375"/> 
      <wp:effectExtent l="0" t="0" r="0" b="0"/> 
      <wp:docPr id="0" name="" descr=""/> 
      <wp:cNvGraphicFramePr> 
       <a:graphicFrameLocks noChangeAspect="true"/> 
      </wp:cNvGraphicFramePr> 
      <a:graphic> 
       <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"> 
       <pic:pic> 
        <pic:nvPicPr> 
        <pic:cNvPr id="1" name=""/> 
        <pic:cNvPicPr/> 
        </pic:nvPicPr> 
        <pic:blipFill> 
        <a:blip r:embed="rId7"/> 
        <a:stretch> 
         <a:fillRect/> 
        </a:stretch> 
        </pic:blipFill> 
        <pic:spPr> 
        <a:xfrm> 
         <a:off x="0" y="0"/> 
         <a:ext cx="952500" cy="333375"/> 
        </a:xfrm> 
        <a:prstGeom prst="rect"> 
         <a:avLst/> 
        </a:prstGeom> 
        </pic:spPr> 
       </pic:pic> 
       </a:graphicData> 
      </a:graphic> 
      </wp:inline> 
     </w:drawing> 

Это вызывает сбой.

+0

Джейсон, я прочитал об этом [здесь] (https://blogs.technet.microsoft.com/hub/2011/ 06/14/use-object-anchors-to-help-place-images-in-word /), и поскольку в моем случае управление контентом контента настроено на то, чтобы плавать за текстом (который генерирует элемент привязки), я попытался без использования этот вариант. Теперь я вижу ту же ошибку, но внутри w: drawing у меня есть два wp: inline. Похоже, мне не нужно добавлять изображение, а редактировать уже существующие - нужно менять код. Далее, чтобы проверить ... – Miki

+0

Вообще говоря, вам лучше разместить свою картинку в текстовом контенте, если вы захотите ее плавать, потому что Microsoft не поддерживает элементы управления плавающим изображением. В Word были способы сделать это, но в прошлом году или в два они вырезали некоторые из этих подходов. – JasonPlutext

0

Благодаря Jason's answer становится ясно, что меня беспокоит. Моя проблема заключалась в том, что я добавлял новое встроенное изображение, в котором у меня уже был один элемент управления контентом изображения. Быстрый выигрыш удаления этого инлайн и добавив одно вы подготовить программно как

BinaryPartAbstractImage imagePart = 
    BinaryPartAbstractImage.createImagePart(wordMLPackage, bytesImage); 
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false); 
Inline inlineOriginal = (Inline) drawing.getAnchorOrInline().get(0);    
drawing.getAnchorOrInline().add(inline);    
drawing.getAnchorOrInline().remove(inlineOriginal); 

Я постараюсь отработать это немного больше, и мы надеемся найти более общий подход как с шаблоном и кода (я попытаюсь изменить этот ответ). Мне нужно проверить, как сохранить/добавить закрепленное изображение в документе, но это еще одна конкретная проблема, с которой я столкнусь. Спасибо Джейсону еще раз!