请先阅读以下资料
https://www.baeldung.com/docx4j
官网
官方论坛(挺有用的,大部分问题在这里都能检索到)
开始
添加maven依赖
<!-- https://mvnrepository.com/artifact/org.docx4j/docx4j -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.0.1</version>
</dependency>
我这边引入的是
6.0.1
版本的docx4j
,而且并没有额外引入jaxb-api
,目前没有发现有什么影响
插入HTML
一些基础的操作在baeldung的资料中已经有了,我就不再提及了,这里主要说明下如何将html文本插入到word中。
在段落中插入Html
public void insertHtml() {
// 构建一个html内容
String content = "<p style=\"color:red\">一段HTML</p>";
String htmlStr = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\"; charset=\"utf-8\"></head><body>" + content + "<p><br/></p></body></html>";
WordprocessingMLPackage aPackage;
try {
// 创建一个临时文件
File tempFile = File.createTempFile("test", ".docx");
aPackage = WordprocessingMLPackage.createPackage();
// 插入段落文本
aPackage.getMainDocumentPart().addParagraphOfText("hello");
// 插入HTML
aPackage.getMainDocumentPart().addAltChunk(AltChunkType.Html, htmlStr.getBytes(Charsets.UTF_8));
// 将构建的word内容保存到临时文件
aPackage.save(tempFile);
} catch (IOException | Docx4JException e) {
e.printStackTrace();
}
}
结果:
在表格中插入Html
public void insertHtmlToTableCell() {
// 构建一个html内容
String content = "<p style=\"color:red\">一段HTML</p>";
WordprocessingMLPackage aPackage;
try {
// 创建一个临时文件
File tempFile = File.createTempFile("test", ".docx");
aPackage = WordprocessingMLPackage.createPackage();
MainDocumentPart mainDocumentPart = aPackage.getMainDocumentPart();
mainDocumentPart.addStyledParagraphOfText("Title", "将HTML插入表格中");
int rowsNum = 2; // 生成表格的行数
int columnNumber = 2; // 生成表格的列数
int writableWidthTwips = aPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips(); // 文档的可写宽度
// 创建表格对象
Tbl tbl = TblFactory.createTable(rowsNum, columnNumber, writableWidthTwips / columnNumber);
// 获取所有行对象
List<Object> rows = tbl.getContent();
setRowData(mainDocumentPart, rows, 0, "第一行", content);
setRowData(mainDocumentPart, rows, 1, "第二行", content);
// 将生成的表格插入到文档中
mainDocumentPart.addObject(tbl);
// 将构建的word内容保存到临时文件
aPackage.save(tempFile);
} catch (IOException | Docx4JException e) {
e.printStackTrace();
}
}
/**
* 设置生成的教案word的行数据
* @param mainDoc MainDocumentPart对象
* @param rows 创建的Tbl对象的所有行对象
* @param rowIndex 操作的行的索引
* @param label 第一列插入的内容
* @param htmlContent 第二列插入的html内容(只需要核心html段就可以了)
* @throws InvalidFormatException
*/
private void setRowData(MainDocumentPart mainDoc, List<Object> rows, int rowIndex, String label, String htmlContent) throws InvalidFormatException {
// 获取当前行
Tr tr = (Tr) rows.get(rowIndex);
// 获取所有列对象
List<Object> cells = tr.getContent();
Tc labelTc = (Tc) cells.get(0); // label列
Tc valueTc = (Tc) cells.get(1); // content列
// 设置label
labelTc.getContent().add(createLabelP(label));
// 设置content
if (htmlContent != null) {
/*
这里需要格外注意:
1. 必须额外加上<p><br/></p>,其中<br/>可为其它标签或非空内容,否则会导致生成的word有错误,无法打开
2. 需要设置html的字符集,否则html内容在部分word版本或跨平台word中会出现中文乱码的情况
*/
String contentStr = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\"; charset=\"utf-8\"></head><body>" + htmlContent + "<p><br/></p></body></html>";
// 创建并设置AlternativeFormatInputPart
AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/hw" + rowIndex + ".html")); //CAUTION: each html part needs a new name!!
afiPart.setBinaryData(contentStr.getBytes(Charsets.UTF_8));
afiPart.setContentType(new ContentType("text/html"));
// 创建CTAltChunk
Relationship altChunkRel = mainDoc.addTargetPart(afiPart);
CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk();
ac.setId(altChunkRel.getId());
// 将ac写入第二列(前面的索引好像是指在哪个位置插入,具体自己查查吧~~~)
valueTc.getContent().set(0, ac);
}
}
/**
* 创建普通的Label的样式配置
* @param text 内容
* @return 一个P节点
*/
private P createLabelP(String text) {
ObjectFactory factory = Context.getWmlObjectFactory();
P p = factory.createP();
R r = factory.createR();
Text t = factory.createText();
t.setValue(text);
r.getContent().add(t);
p.getContent().add(r);
RPr rpr = factory.createRPr();
BooleanDefaultTrue b = new BooleanDefaultTrue();
rpr.setB(b);
BooleanDefaultTrue caps = new BooleanDefaultTrue();
rpr.setCaps(caps);
Color green = factory.createColor();
green.setVal("black");
rpr.setColor(green);
// 设置字体大小
HpsMeasure size = new HpsMeasure();
size.setVal(new BigInteger("18"));
rpr.setSz(size);
rpr.setSzCs(size);
// 设置字体
RFonts rFonts = rpr.getRFonts();
if (rFonts==null) {
rFonts = new RFonts();
rpr.setRFonts(rFonts);
}
rFonts.setEastAsia("微软雅黑");
r.setRPr(rpr);
return p;
}
结果:
一些坑
- 在插入HTML的时候,一定要是完整的html内容(以<html>节点开口)
- 需要设置html的字符集,否则html内容在部分word版本或跨平台word中会出现中文乱码的情况
- 当在表格中插入HTML内容时,最后在</body>节点之前再添加个节点,如:
<p><br/></p>
,不然可能会遇到生成的word错误,无法打开的情况(我就遇到过:当<body>节点中的内容仅为一个<table>节点时)