我希望使用Apache将HTML作为altChunk添加到DOCX文件中。我知道doc4jx可以使用更简单的API来实现这一点,但出于技术原因,我需要使用Apache。
使用CT类对xml执行低级操作有点棘手。我可以用以下代码创建一个altChunk:
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”中呢?
发布于 2018-12-01 07:46:04
在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
文件结构中实现的?
/word/*.html
文件在*.docx
ZIP
文件中。例如,这些在/word/document.xml
中被Id引用为<w:altChunk r:id="htmlDoc1"/>
。例如,Ids与/word/*.html
文件之间的关系在/word/_rels/document.xml.rels
中作为<Relationship Id="htmlDoc1" Target="htmlDoc1.html" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk"/>
给出。
因此,我们首先需要用于POIXMLDocumentPart
文件的/word/*.html
文件和用于Ids和/word/*.html
文件之间关系的POIXMLRelation
s。下面的代码提供了一个包装类,它扩展了POIXMLDocumentPart,用于*.docx ZIP存档中的/word/htmlDoc#.html
文件。这还提供了操作HTML的方法。此外,它还提供了一种方法,用于在/word/htmlDoc#.html
ZIP存档中创建*.docx文件并创建与之的关系。
代码:
import java.io.*;
import org.apache.poi.*;
import org.apache.poi.ooxml.*;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.xwpf.usermodel.*;
public class CreateWordWithHTMLaltChunk {
//a method for creating the htmlDoc /word/htmlDoc#.html in the *.docx ZIP archive
//String id will be htmlDoc#.
private static MyXWPFHtmlDocument createHtmlDoc(XWPFDocument document, String id) throws Exception {
OPCPackage oPCPackage = document.getPackage();
PackagePartName partName = PackagingURIHelper.createPartName("/word/" + id + ".html");
PackagePart part = oPCPackage.createPart(partName, "text/html");
MyXWPFHtmlDocument myXWPFHtmlDocument = new MyXWPFHtmlDocument(part, id);
document.addRelation(myXWPFHtmlDocument.getId(), new XWPFHtmlRelation(), myXWPFHtmlDocument);
return myXWPFHtmlDocument;
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph;
XWPFRun run;
MyXWPFHtmlDocument myXWPFHtmlDocument;
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Default paragraph followed by first HTML chunk.");
myXWPFHtmlDocument = createHtmlDoc(document, "htmlDoc1");
myXWPFHtmlDocument.setHtml(myXWPFHtmlDocument.getHtml().replace("<body></body>",
"<body><p>Simple <b>HTML</b> <i>formatted</i> <u>text</u></p></body>"));
document.getDocument().getBody().addNewAltChunk().setId(myXWPFHtmlDocument.getId());
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("Default paragraph followed by second HTML chunk.");
myXWPFHtmlDocument = createHtmlDoc(document, "htmlDoc2");
myXWPFHtmlDocument.setHtml(myXWPFHtmlDocument.getHtml().replace("<body></body>",
"<body>" +
"<table>"+
"<caption>A table></caption>" +
"<tr><th>Name</th><th>Date</th><th>Amount</th></tr>" +
"<tr><td>John Doe</td><td>2018-12-01</td><td>1,234.56</td></tr>" +
"</table>" +
"</body>"
));
document.getDocument().getBody().addNewAltChunk().setId(myXWPFHtmlDocument.getId());
FileOutputStream out = new FileOutputStream("CreateWordWithHTMLaltChunk.docx");
document.write(out);
out.close();
document.close();
}
//a wrapper class for the htmlDoc /word/htmlDoc#.html in the *.docx ZIP archive
//provides methods for manipulating the HTML
//TODO: We should *not* using String methods for manipulating HTML!
private static class MyXWPFHtmlDocument extends POIXMLDocumentPart {
private String html;
private String id;
private MyXWPFHtmlDocument(PackagePart part, String id) throws Exception {
super(part);
this.html = "<!DOCTYPE html><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><style></style><title>HTML import</title></head><body></body>";
this.id = id;
}
private String getId() {
return id;
}
private String getHtml() {
return html;
}
private void setHtml(String html) {
this.html = html;
}
@Override
protected void commit() throws IOException {
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.write(html);
writer.close();
out.close();
}
}
//the XWPFRelation for /word/htmlDoc#.html
private final static class XWPFHtmlRelation extends POIXMLRelation {
private XWPFHtmlRelation() {
super(
"text/html",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk",
"/word/htmlDoc#.html");
}
}
}
注意:由于使用了altChunk
,这段代码需要ooxml-schemas-*.jar
中提到的所有模式的完整jar。
结果:
发布于 2018-12-02 04:00:47
基于CTBodyImpl.get_store().add_element_user(QName),我用阿克塞尔·里希特的回答替换了对CTBody.addNewAltChunk()的调用,这消除了添加的对ooxml-模式的15 to依赖。由于这是在桌面应用程序中使用,我们试图保持应用程序的大小尽可能小。如果对其他人有帮助的话:
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);
}
}
发布于 2020-04-27 16:13:31
这个特性在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;
https://stackoverflow.com/questions/53564028
复制相似问题