Как обеспечить последовательность атрибутов ctdocument в apache poi xwpf
РЕДАКТИРОВАТЬ [FIX] - см. Внизу.
MSOffice генерирует этот элемент во всех документах с некоторым базовым знанием того, что ограничения NS должны быть в определенной степени соблюдены...
Пример документа MS:
<w:document
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
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"
mc:Ignorable="w14 w15 wp14">
<!--whatever-->
</w:document>
Пример вывода POI
<w:document
mc:Ignorable="w14 w15 wp14"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
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">
<!--whatever-->
</w:document>
Обратите внимание, что элемент MC:IGNORABLE смещен... Ручное изменение этого элемента внутри самого архива docx "исправляет" ошибку, сгенерированную программой MSOffice, которая указывает ошибку в строке 2, столбец 0.
Пока я пробовал:
xwpfDocument.getDocument().getDomNode()
^ попытался изменить, удалить и добавить атрибуты в правильном порядке... не работает, так как кажется, что смещение происходит где-то в процедуре XWPFDocument.write().
Я также попытался извлечь файл document.xml из архива docx, изменить его и вставить обратно в архив... и это, похоже, не работает... Проблемы с CRC...
Есть ли способ получить доступ к OPCPackage или части или что-нибудь, чтобы разрешить прямой вызов встроенного "recalculateAttributesRelativeToNS" в этом элементе?
... или как альтернатива.. как мне автоматизировать dom-изменения в файле XML документа внутри архива и при этом обеспечить совместимость с ms?
[РЕДАКТИРОВАТЬ: "XY"]
Такое поведение проявляется в следующем сценарии:
fis = new FileInputStream(new File(path));
XWPFPicture picture = imageRun.addPicture(fis, XWPFDocument.PICTURE_TYPE_PNG, path, Units.toEMU(450), Units.toEMU(290));
Документ открывается нормально. вопроса нету.
Добавление этой строки (я знаю, что это технически неверно, однако об ошибке не следует сообщать в строке 2- столбец 0, как это следует сообщать далее в xml), все портит.
picture.getCTPicture().getSpPr().addNewEffectLst().addNewOuterShdw().setBlurRad(10000);
С добавлением этой строки атрибуты w:document переходят в состояние 2 (пример poi), тем самым вызывая процедуру аннулирования NS MS-схемы MSOffice.
Атрибуты верны. Порядок неверный. Перемещение атрибута mc:ignorable вручную в конец списка атрибутов решает проблему, и документ загружается без проблем.
Скорее всего, это связано с тем, что (в правильной реализации) атрибут xmlns:mc предшествует атрибуту mc:ignorable в списке атрибутов, тогда как в выводе poi его нет (mc:Ignorable - первый элемент в списке).
отсюда... вопрос.
дополнительно... список импорта:
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.POIXMLProperties;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
все в этом классе является автономным.
РЕДАКТИРОВАТЬ [FIX]
Исправление состоит в добавлении второй строки в этот фрагмент.
picture.getCTPicture().getSpPr().addNewEffectLst().addNewInnerShdw().setBlurRad(Units.toEMU(3));
picture.getCTPicture().getSpPr().getEffectLst().getInnerShdw().addNewPrstClr().setVal(org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal.BLACK);
Еще раз спасибо, @AxelRichter.
1 ответ
Указание на строку 2 столбца 0 в ошибке вводит в заблуждение. Если вы посмотрите на /word/document.xml
тогда всего 2 строки. Объявление XML в строке 1 и все остальные XML в строке 2.
Ваша проблема в том, что определение схемы CT_OuterShadowEffect
является:
<xsd:complexType name="CT_OuterShadowEffect">
<xsd:sequence>
<xsd:group ref="EG_ColorChoice" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="blurRad" type="ST_PositiveCoordinate" use="optional" default="0"/>
<xsd:attribute name="dist" type="ST_PositiveCoordinate" use="optional" default="0"/>
<xsd:attribute name="dir" type="ST_PositiveFixedAngle" use="optional" default="0"/>
<xsd:attribute name="sx" type="ST_Percentage" use="optional" default="100%"/>
<xsd:attribute name="sy" type="ST_Percentage" use="optional" default="100%"/>
<xsd:attribute name="kx" type="ST_FixedAngle" use="optional" default="0"/>
<xsd:attribute name="ky" type="ST_FixedAngle" use="optional" default="0"/>
<xsd:attribute name="algn" type="ST_RectAlignment" use="optional" default="b"/>
<xsd:attribute name="rotWithShape" type="xsd:boolean" use="optional" default="true"/>
</xsd:complexType>
Как видите, EG_ColorChoice
должно произойти 1 раз. Другими словами: должна быть настройка цвета для CTOuterShadowEffect
,
Следующий код работает для меня:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
public class WordInsertPicturesWithShadow {
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("source.docx"));
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("The picture: ");
InputStream in = new FileInputStream("samplePict.jpeg");
XWPFPicture picture = run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", Units.toEMU(100), Units.toEMU(100));
in.close();
picture.getCTPicture().getSpPr().addNewEffectLst().addNewOuterShdw().setBlurRad(50000);
//picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDist(100000);
//picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setDir(2700000);
//picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setAlgn(
// org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment.TL);
//picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().setRotWithShape(false);
picture.getCTPicture().getSpPr().getEffectLst().getOuterShdw().addNewPrstClr().setVal(
org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal.BLACK);
run.setText(" text after the picture.");
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("result.docx");
document.write(out);
out.close();
document.close();
}
}