Java 如何使用ApachePOI将altChunk元素添加到XWPFDocument
我想使用apachepoi将HTML作为altChunk添加到DOCX文件中。我知道doc4jx可以用一个更简单的API实现这一点,但出于技术原因,我需要使用ApachePOI 使用CT类对xml进行底层处理有点棘手。我可以使用以下代码创建altChunk:Java 如何使用ApachePOI将altChunk元素添加到XWPFDocument,java,apache-poi,Java,Apache Poi,我想使用apachepoi将HTML作为altChunk添加到DOCX文件中。我知道doc4jx可以用一个更简单的API实现这一点,但出于技术原因,我需要使用ApachePOI 使用CT类对xml进行底层处理有点棘手。我可以使用以下代码创建altChunk: import java.io.File; import java.io.FileOutputStream; import javax.xml.namespace.QName; import org.apache.poi.xwpf.use
import java.io.File;
import java.io.FileOutputStream;
import javax.xml.namespace.QName;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.impl.values.XmlComplexContentImpl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTBodyImpl;
public class AltChunkTest {
public static void main(String[] args) throws Exception {
XWPFDocument doc = new XWPFDocument();
doc.createParagraph().createRun().setText("AltChunk below:");
QName ALTCHUNK = new QName ( "http://schemas.openxmlformats.org/wordprocessingml/2006/main" , "altChunk" ) ;
CTDocument1 ctDoc = doc.getDocument() ;
CTBodyImpl ctBody = (CTBodyImpl) ctDoc. getBody();
XmlComplexContentImpl xcci = ( XmlComplexContentImpl ) ctBody.get_store().add_element_user(ALTCHUNK);
// what's need to now add "<b>Hello World!</b>"
FileOutputStream out = new FileOutputStream(new File("test.docx"));
doc.write(out);
}
}
但是现在如何将html内容添加到“xcci”it?在Office Open XML for Word*.docx中,altChunk提供了一种使用纯html描述文档部分的方法
关于altChunk的两个重要注意事项:
第一:它仅用于导入内容。如果使用Word打开并保存文档,则新保存的文档将不包含替代格式内容部分,也不包含引用它的altChunk标记。Word将所有导入的内容保存为默认的Office Open XML元素
第二:除了Word之外,大多数能够读取*.docx的应用程序根本不会读取altChunk内容。例如,在打开*.docx文件时,Libreoffice或OpenOffice Writer不会读取altChunk内容,apache poi也不会读取altChunk内容
altChunk是如何在*.docx ZIP文件结构中实现的
*.docx ZIP文件中有/word/*.html文件。例如,/word/document.xml中的Id引用了这些文件。例如,/word/_rels/document.xml.rels中给出了ID和/word/*.html文件之间的关系
因此,我们首先需要POIXMLDocumentParts用于/word/*.html文件,POIXMLRelations用于ID和/word/*.html文件之间的关系。下面的代码提供了一个包装器类,该类扩展了*.docx ZIP归档文件中/word/htmlDoc.html文件的POIXMLDocumentPart。这还提供了操作HTML的方法。此外,它还提供了一种方法,用于在*.docx ZIP归档文件中创建/word/htmlDoc.html文件并创建与该文件的关系
代码:
注意:由于使用altChunk,这段代码需要所有模式的完整jar,如中所述的ooxml模式-*.jar
结果:
在Office Open XML for Word*.docx中,altChunk提供了一种使用纯HTML描述文档部分的方法
关于altChunk的两个重要注意事项:
第一:它仅用于导入内容。如果使用Word打开并保存文档,则新保存的文档将不包含替代格式内容部分,也不包含引用它的altChunk标记。Word将所有导入的内容保存为默认的Office Open XML元素
第二:除了Word之外,大多数能够读取*.docx的应用程序根本不会读取altChunk内容。例如,在打开*.docx文件时,Libreoffice或OpenOffice Writer不会读取altChunk内容,apache poi也不会读取altChunk内容
altChunk是如何在*.docx ZIP文件结构中实现的
*.docx ZIP文件中有/word/*.html文件。例如,/word/document.xml中的Id引用了这些文件。例如,/word/_rels/document.xml.rels中给出了ID和/word/*.html文件之间的关系
因此,我们首先需要POIXMLDocumentParts用于/word/*.html文件,POIXMLRelations用于ID和/word/*.html文件之间的关系。下面的代码提供了一个包装器类,该类扩展了*.docx ZIP归档文件中/word/htmlDoc.html文件的POIXMLDocumentPart。这还提供了操作HTML的方法。此外,它还提供了一种方法,用于在*.docx ZIP归档文件中创建/word/htmlDoc.html文件并创建与该文件的关系
代码:
注意:由于使用altChunk,这段代码需要所有模式的完整jar,如中所述的ooxml模式-*.jar
结果:
基于,我将对CTBody.addNewAltChunk的调用替换为CTBodyImpl.get\u store.add\u element\u userQName,从而消除了对的额外15MB依赖。因为这是在桌面应用程序中使用的,所以我们尝试将应用程序大小保持尽可能小。如果可能对其他任何人有帮助:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.namespace.QName;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.SimpleValue;
import org.apache.xmlbeans.impl.values.XmlComplexContentImpl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTBodyImpl;
public class AltChunkTest {
public static void main(String[] args) throws Exception {
XWPFDocument doc = new XWPFDocument();
doc.createParagraph().createRun().setText("AltChunk below:");
addHtml(doc,"chunk1","<!DOCTYPE html><html><head><style></style><title></title></head><body><b>Hello World!</b></body></html>");
FileOutputStream out = new FileOutputStream(new File("test.docx"));
doc.write(out);
}
static void addHtml(XWPFDocument doc, String id,String html) throws Exception {
OPCPackage oPCPackage = doc.getPackage();
PackagePartName partName = PackagingURIHelper.createPartName("/word/" + id + ".html");
PackagePart part = oPCPackage.createPart(partName, "text/html");
class HtmlRelation extends POIXMLRelation {
private HtmlRelation() {
super( "text/html",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk",
"/word/htmlDoc#.html");
}
}
class HtmlDocumentPart extends POIXMLDocumentPart {
private HtmlDocumentPart(PackagePart part) throws Exception {
super(part);
}
@Override
protected void commit() throws IOException {
try (OutputStream out = part.getOutputStream()) {
try (Writer writer = new OutputStreamWriter(out, "UTF-8")) {
writer.write(html);
}
}
}
};
HtmlDocumentPart documentPart = new HtmlDocumentPart(part);
doc.addRelation(id, new HtmlRelation(), documentPart);
CTBodyImpl b = (CTBodyImpl) doc.getDocument().getBody();
QName ALTCHUNK = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "altChunk");
XmlComplexContentImpl altchunk = (XmlComplexContentImpl) b.get_store().add_element_user(ALTCHUNK);
QName ID = new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id");
SimpleValue target = (SimpleValue)altchunk.get_store().add_attribute_user(ID);
target.setStringValue(id);
}
}
基于,我将对CTBody.addNewAltChunk的调用替换为CTBodyImpl.get\u store.add\u element\u userQName,从而消除了对的额外15MB依赖。因为这是在桌面应用程序中使用的,所以我们尝试将应用程序大小保持尽可能小。如果可能对其他任何人有帮助:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.namespace.QName;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.xmlbeans.SimpleValue;
import org.apache.xmlbeans.impl.values.XmlComplexContentImpl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTBodyImpl;
public class AltChunkTest {
public static void main(String[] args) throws Exception {
XWPFDocument doc = new XWPFDocument();
doc.createParagraph().createRun().setText("AltChunk below:");
addHtml(doc,"chunk1","<!DOCTYPE html><html><head><style></style><title></title></head><body><b>Hello World!</b></body></html>");
FileOutputStream out = new FileOutputStream(new File("test.docx"));
doc.write(out);
}
static void addHtml(XWPFDocument doc, String id,String html) throws Exception {
OPCPackage oPCPackage = doc.getPackage();
PackagePartName partName = PackagingURIHelper.createPartName("/word/" + id + ".html");
PackagePart part = oPCPackage.createPart(partName, "text/html");
class HtmlRelation extends POIXMLRelation {
private HtmlRelation() {
super( "text/html",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk",
"/word/htmlDoc#.html");
}
}
class HtmlDocumentPart extends POIXMLDocumentPart {
private HtmlDocumentPart(PackagePart part) throws Exception {
super(part);
}
@Override
protected void commit() throws IOException {
try (OutputStream out = part.getOutputStream()) {
try (Writer writer = new OutputStreamWriter(out, "UTF-8")) {
writer.write(html);
}
}
}
};
HtmlDocumentPart documentPart = new HtmlDocumentPart(part);
doc.addRelation(id, new HtmlRelation(), documentPart);
CTBodyImpl b = (CTBodyImpl) doc.getDocument().getBody();
QName ALTCHUNK = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "altChunk");
XmlComplexContentImpl altchunk = (XmlComplexContentImpl) b.get_store().add_element_user(ALTCHUNK);
QName ID = new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id");
SimpleValue target = (SimpleValue)altchunk.get_store().add_attribute_user(ID);
target.setStringValue(id);
}
}
这个特性在poi ooxml 4.0.0中是正常的,其中类POIXMLDocumentPart和POIXMLRelation位于包org.apache.poi.ooxml中*
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLRelation;
但是我们如何在poi ooxml 3.9中使用,在那里类与org.apache.poi几乎没有什么不同*
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLRelation;
这个特性在poi ooxml 4.0.0中是正常的,其中类POIXMLDocumentPart和POIXMLRelation位于包org.apache.poi.ooxml中*
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLRelation;
但是我们如何在poi ooxml 3.9中使用,在那里类与org.apache.poi几乎没有什么不同*
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLRelation;
对于手动将docx文件编辑为ZIP、d的用户
在上,不要忘记添加[Content\u Types].xml。对于手动将docx文件编辑为ZIP的用户,不要忘记添加[Content\u Types].xml。