請(qǐng)先閱讀以下資料
https://www.baeldung.com/docx4j
官網(wǎng)
官方論壇(挺有用的,大部分問(wèn)題在這里都能檢索到)
開(kāi)始
添加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,而且并沒(méi)有額外引入jaxb-api,目前沒(méi)有發(fā)現(xiàn)有什么影響
插入HTML
一些基礎(chǔ)的操作在baeldung的資料中已經(jīng)有了,我就不再提及了,這里主要說(shuō)明下如何將html文本插入到word中。
在段落中插入Html
public void insertHtml() {
// 構(gòu)建一個(gè)html內(nèi)容
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 {
// 創(chuàng)建一個(gè)臨時(shí)文件
File tempFile = File.createTempFile("test", ".docx");
aPackage = WordprocessingMLPackage.createPackage();
// 插入段落文本
aPackage.getMainDocumentPart().addParagraphOfText("hello");
// 插入HTML
aPackage.getMainDocumentPart().addAltChunk(AltChunkType.Html, htmlStr.getBytes(Charsets.UTF_8));
// 將構(gòu)建的word內(nèi)容保存到臨時(shí)文件
aPackage.save(tempFile);
} catch (IOException | Docx4JException e) {
e.printStackTrace();
}
}
結(jié)果:

image
在表格中插入Html
public void insertHtmlToTableCell() {
// 構(gòu)建一個(gè)html內(nèi)容
String content = "<p style=\"color:red\">一段HTML</p>";
WordprocessingMLPackage aPackage;
try {
// 創(chuàng)建一個(gè)臨時(shí)文件
File tempFile = File.createTempFile("test", ".docx");
aPackage = WordprocessingMLPackage.createPackage();
MainDocumentPart mainDocumentPart = aPackage.getMainDocumentPart();
mainDocumentPart.addStyledParagraphOfText("Title", "將HTML插入表格中");
int rowsNum = 2; // 生成表格的行數(shù)
int columnNumber = 2; // 生成表格的列數(shù)
int writableWidthTwips = aPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips(); // 文檔的可寫(xiě)寬度
// 創(chuàng)建表格對(duì)象
Tbl tbl = TblFactory.createTable(rowsNum, columnNumber, writableWidthTwips / columnNumber);
// 獲取所有行對(duì)象
List<Object> rows = tbl.getContent();
setRowData(mainDocumentPart, rows, 0, "第一行", content);
setRowData(mainDocumentPart, rows, 1, "第二行", content);
// 將生成的表格插入到文檔中
mainDocumentPart.addObject(tbl);
// 將構(gòu)建的word內(nèi)容保存到臨時(shí)文件
aPackage.save(tempFile);
} catch (IOException | Docx4JException e) {
e.printStackTrace();
}
}
/**
* 設(shè)置生成的教案word的行數(shù)據(jù)
* @param mainDoc MainDocumentPart對(duì)象
* @param rows 創(chuàng)建的Tbl對(duì)象的所有行對(duì)象
* @param rowIndex 操作的行的索引
* @param label 第一列插入的內(nèi)容
* @param htmlContent 第二列插入的html內(nèi)容(只需要核心html段就可以了)
* @throws InvalidFormatException
*/
private void setRowData(MainDocumentPart mainDoc, List<Object> rows, int rowIndex, String label, String htmlContent) throws InvalidFormatException {
// 獲取當(dāng)前行
Tr tr = (Tr) rows.get(rowIndex);
// 獲取所有列對(duì)象
List<Object> cells = tr.getContent();
Tc labelTc = (Tc) cells.get(0); // label列
Tc valueTc = (Tc) cells.get(1); // content列
// 設(shè)置label
labelTc.getContent().add(createLabelP(label));
// 設(shè)置content
if (htmlContent != null) {
/*
這里需要格外注意:
1. 必須額外加上<p><br/></p>,其中<br/>可為其它標(biāo)簽或非空內(nèi)容,否則會(huì)導(dǎo)致生成的word有錯(cuò)誤,無(wú)法打開(kāi)
2. 需要設(shè)置html的字符集,否則html內(nèi)容在部分word版本或跨平臺(tái)word中會(huì)出現(xiàn)中文亂碼的情況
*/
String contentStr = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\"; charset=\"utf-8\"></head><body>" + htmlContent + "<p><br/></p></body></html>";
// 創(chuàng)建并設(shè)置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"));
// 創(chuàng)建CTAltChunk
Relationship altChunkRel = mainDoc.addTargetPart(afiPart);
CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk();
ac.setId(altChunkRel.getId());
// 將ac寫(xiě)入第二列(前面的索引好像是指在哪個(gè)位置插入,具體自己查查吧~~~)
valueTc.getContent().set(0, ac);
}
}
/**
* 創(chuàng)建普通的Label的樣式配置
* @param text 內(nèi)容
* @return 一個(gè)P節(jié)點(diǎn)
*/
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);
// 設(shè)置字體大小
HpsMeasure size = new HpsMeasure();
size.setVal(new BigInteger("18"));
rpr.setSz(size);
rpr.setSzCs(size);
// 設(shè)置字體
RFonts rFonts = rpr.getRFonts();
if (rFonts==null) {
rFonts = new RFonts();
rpr.setRFonts(rFonts);
}
rFonts.setEastAsia("微軟雅黑");
r.setRPr(rpr);
return p;
}
結(jié)果:

image
一些坑
- 在插入HTML的時(shí)候,一定要是完整的html內(nèi)容(以<html>節(jié)點(diǎn)開(kāi)口)
- 需要設(shè)置html的字符集,否則html內(nèi)容在部分word版本或跨平臺(tái)word中會(huì)出現(xiàn)中文亂碼的情況
- 當(dāng)在表格中插入HTML內(nèi)容時(shí),最后在</body>節(jié)點(diǎn)之前再添加個(gè)節(jié)點(diǎn),如:
<p><br/></p>,不然可能會(huì)遇到生成的word錯(cuò)誤,無(wú)法打開(kāi)的情況(我就遇到過(guò):當(dāng)<body>節(jié)點(diǎn)中的內(nèi)容僅為一個(gè)<table>節(jié)點(diǎn)時(shí))