前段时间调研POI和docx4j对word的操作,结合网上其他大佬的代码,自己补充写了并整合HTML转word的相关的公用方法。
用到的jar包
‘org.docx4j:docx4j:6.0.1’,
‘org.docx4j:xhtmlrenderer:3.0.0’,
‘org.docx4j:xmlgraphics-commons:2.3’,
‘org.docx4j:docx4j-ImportXHTML:6.0.1’,
import org.apache.commons.lang.StringUtils;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.PageSizePaper;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import javax.xml.bind.JAXBElement;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2019/9/3.
*/
public class Docx4jWord {
private WordprocessingMLPackage wordMLPackage = null;
private MainDocumentPart mp = null;
private ObjectFactory factory = null;
private Docx4jWord(WordprocessingMLPackage wordMLPackage) {
this.wordMLPackage = wordMLPackage;
this.mp = wordMLPackage.getMainDocumentPart();
this.factory = Context.getWmlObjectFactory();
}
public static Docx4jWord createWord() throws Exception {
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
return new Docx4jWord(wordMLPackage);
}
public static Docx4jWord createWord(PageSizePaper pageSizePaper, Boolean formatType) throws Exception {
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage(pageSizePaper, formatType);
return new Docx4jWord(wordMLPackage);
}
public WordprocessingMLPackage getWordMLPackage() {
return wordMLPackage;
}
public MainDocumentPart getMp() {
return mp;
}
public void setMp(MainDocumentPart mp) {
this.mp = mp;
}
public ObjectFactory getFactory() {
return factory;
}
public void setFactory(ObjectFactory factory) {
this.factory = factory;
}
//以下为生成Word通用方法/
/**
* 解决解析html里不识别
*
* @param html
* @return
* @throws Exception
*/
public String setHTMLHead(String html) throws Exception {
html = "<!DOCTYPE html [<!ENTITY nbsp \" \"><!ENTITY iexcl \"¡\"><!ENTITY cent \"¢\"><!ENTITY pound \"£\"><!ENTITY curren \"¤\"><!ENTITY yen \"¥\"><!ENTITY brvbar \"¦\"><!ENTITY sect \"§\"><!ENTITY uml \"¨\"><!ENTITY copy \"©\"><!ENTITY ordf \"ª\"><!ENTITY laquo \"«\"><!ENTITY not \"¬\"><!ENTITY shy \"­\"><!ENTITY reg \"®\"><!ENTITY macr \"¯\"><!ENTITY deg \"°\"><!ENTITY plusmn \"±\"><!ENTITY sup2 \"²\"><!ENTITY sup3 \"³\"><!ENTITY acute \"´\"><!ENTITY micro \"µ\"><!ENTITY para \"¶\"><!ENTITY middot \"·\"><!ENTITY cedil \"¸\"><!ENTITY sup1 \"¹\"><!ENTITY ordm \"º\"><!ENTITY raquo \"»\"><!ENTITY frac14 \"¼\"><!ENTITY frac12 \"½\"><!ENTITY frac34 \"¾\"><!ENTITY iquest \"¿\"><!ENTITY Agrave \"À\"><!ENTITY Aacute \"Á\"><!ENTITY Acirc \"Â\"><!ENTITY Atilde \"Ã\"><!ENTITY Auml \"Ä\"><!ENTITY Aring \"Å\"><!ENTITY AElig \"Æ\"><!ENTITY Ccedil \"Ç\"><!ENTITY Egrave \"È\"><!ENTITY Eacute \"É\"><!ENTITY Ecirc \"Ê\"><!ENTITY Euml \"Ë\"><!ENTITY Igrave \"Ì\"><!ENTITY Iacute \"Í\"><!ENTITY Icirc \"Î\"><!ENTITY Iuml \"Ï\"><!ENTITY ETH \"Ð\"><!ENTITY Ntilde \"Ñ\"><!ENTITY Ograve \"Ò\"><!ENTITY Oacute \"Ó\"><!ENTITY Ocirc \"Ô\"><!ENTITY Otilde \"Õ\"><!ENTITY Ouml \"Ö\"><!ENTITY times \"×\"><!ENTITY Oslash \"Ø\"><!ENTITY Ugrave \"Ù\"><!ENTITY Uacute \"Ú\"><!ENTITY Ucirc \"Û\"><!ENTITY Uuml \"Ü\"><!ENTITY Yacute \"Ý\"><!ENTITY THORN \"Þ\"><!ENTITY szlig \"ß\"><!ENTITY agrave \"à\"><!ENTITY aacute \"á\"><!ENTITY acirc \"â\"><!ENTITY atilde \"ã\"><!ENTITY auml \"ä\"><!ENTITY aring \"å\"><!ENTITY aelig \"æ\"><!ENTITY ccedil \"ç\"><!ENTITY egrave \"è\"><!ENTITY eacute \"é\"><!ENTITY ecirc \"ê\"><!ENTITY euml \"ë\"><!ENTITY igrave \"ì\"><!ENTITY iacute \"í\"><!ENTITY icirc \"î\"><!ENTITY iuml \"ï\"><!ENTITY eth \"ð\"><!ENTITY ntilde \"ñ\"><!ENTITY ograve \"ò\"><!ENTITY oacute \"ó\"><!ENTITY ocirc \"ô\"><!ENTITY otilde \"õ\"><!ENTITY ouml \"ö\"><!ENTITY divide \"÷\"><!ENTITY oslash \"ø\"><!ENTITY ugrave \"ù\"><!ENTITY uacute \"ú\"><!ENTITY ucirc \"û\"><!ENTITY uuml \"ü\"><!ENTITY yacute \"ý\"><!ENTITY thorn \"þ\"><!ENTITY yuml \"ÿ\"><!ENTITY fnof \"ƒ\"><!ENTITY Alpha \"Α\"><!ENTITY Beta \"Β\"><!ENTITY Gamma \"Γ\"><!ENTITY Delta \"Δ\"><!ENTITY Epsilon \"Ε\"><!ENTITY Zeta \"Ζ\"><!ENTITY Eta \"Η\"><!ENTITY Theta \"Θ\"><!ENTITY Iota \"Ι\"><!ENTITY Kappa \"Κ\"><!ENTITY Lambda \"Λ\"><!ENTITY Mu \"Μ\"><!ENTITY Nu \"Ν\"><!ENTITY Xi \"Ξ\"><!ENTITY Omicron \"Ο\"><!ENTITY Pi \"Π\"><!ENTITY Rho \"Ρ\"><!ENTITY Sigma \"Σ\"><!ENTITY Tau \"Τ\"><!ENTITY Upsilon \"Υ\"><!ENTITY Phi \"Φ\"><!ENTITY Chi \"Χ\"><!ENTITY Psi \"Ψ\"><!ENTITY Omega \"Ω\"><!ENTITY alpha \"α\"><!ENTITY beta \"β\"><!ENTITY gamma \"γ\"><!ENTITY delta \"δ\"><!ENTITY epsilon \"ε\"><!ENTITY zeta \"ζ\"><!ENTITY eta \"η\"><!ENTITY theta \"θ\"><!ENTITY iota \"ι\"><!ENTITY kappa \"κ\"><!ENTITY lambda \"λ\"><!ENTITY mu \"μ\"><!ENTITY nu \"ν\"><!ENTITY xi \"ξ\"><!ENTITY omicron \"ο\"><!ENTITY pi \"π\"><!ENTITY rho \"ρ\"><!ENTITY sigmaf \"ς\"><!ENTITY sigma \"σ\"><!ENTITY tau \"τ\"><!ENTITY upsilon \"υ\"><!ENTITY phi \"φ\"><!ENTITY chi \"χ\"><!ENTITY psi \"ψ\"><!ENTITY omega \"ω\"><!ENTITY thetasym \"ϑ\"><!ENTITY upsih \"ϒ\"><!ENTITY piv \"ϖ\"><!ENTITY bull \"•\"><!ENTITY hellip \"…\"><!ENTITY prime \"′\"><!ENTITY Prime \"″\"><!ENTITY oline \"‾\"><!ENTITY frasl \"⁄\"><!ENTITY weierp \"℘\"><!ENTITY image \"ℑ\"><!ENTITY real \"ℜ\"><!ENTITY trade \"™\"><!ENTITY alefsym \"ℵ\"><!ENTITY larr \"←\"><!ENTITY uarr \"↑\"><!ENTITY rarr \"→\"><!ENTITY darr \"↓\"><!ENTITY harr \"↔\"><!ENTITY crarr \"↵\"><!ENTITY lArr \"⇐\"><!ENTITY uArr \"⇑\"><!ENTITY rArr \"⇒\"><!ENTITY dArr \"⇓\"><!ENTITY hArr \"⇔\"><!ENTITY forall \"∀\"><!ENTITY part \"∂\"><!ENTITY exist \"∃\"><!ENTITY empty \"∅\"><!ENTITY nabla \"∇\"><!ENTITY isin \"∈\"><!ENTITY notin \"∉\"><!ENTITY ni \"∋\"><!ENTITY prod \"∏\"><!ENTITY sum \"∑\"><!ENTITY minus \"−\"><!ENTITY lowast \"∗\"><!ENTITY radic \"√\"><!ENTITY prop \"∝\"><!ENTITY infin \"∞\"><!ENTITY ang \"∠\"><!ENTITY and \"∧\"><!ENTITY or \"∨\"><!ENTITY cap \"∩\"><!ENTITY cup \"∪\"><!ENTITY int \"∫\"><!ENTITY there4 \"∴\"><!ENTITY sim \"∼\"><!ENTITY cong \"≅\"><!ENTITY asymp \"≈\"><!ENTITY ne \"≠\"><!ENTITY equiv \"≡\"><!ENTITY le \"≤\"><!ENTITY ge \"≥\"><!ENTITY sub \"⊂\"><!ENTITY sup \"⊃\"><!ENTITY nsub \"⊄\"><!ENTITY sube \"⊆\"><!ENTITY supe \"⊇\"><!ENTITY oplus \"⊕\"><!ENTITY otimes \"⊗\"><!ENTITY perp \"⊥\"><!ENTITY sdot \"⋅\"><!ENTITY lceil \"⌈\"><!ENTITY rceil \"⌉\"><!ENTITY lfloor \"⌊\"><!ENTITY rfloor \"⌋\"><!ENTITY lang \"〈\"><!ENTITY rang \"〉\"><!ENTITY loz \"◊\"><!ENTITY spades \"♠\"><!ENTITY clubs \"♣\"><!ENTITY hearts \"♥\"><!ENTITY diams \"♦\"><!ENTITY quot \""\"><!ENTITY amp \"&\"><!ENTITY lt \"<\"><!ENTITY gt \">\"><!ENTITY OElig \"Œ\"><!ENTITY oelig \"œ\"><!ENTITY Scaron \"Š\"><!ENTITY scaron \"š\"><!ENTITY Yuml \"Ÿ\"><!ENTITY circ \"ˆ\"><!ENTITY tilde \"˜\"><!ENTITY ensp \" \"><!ENTITY emsp \" \"><!ENTITY thinsp \" \"><!ENTITY zwnj \"‌\"><!ENTITY zwj \"‍\"><!ENTITY lrm \"‎\"><!ENTITY rlm \"‏\"><!ENTITY ndash \"–\"><!ENTITY mdash \"—\"><!ENTITY lsquo \"‘\"><!ENTITY rsquo \"’\"><!ENTITY sbquo \"‚\"><!ENTITY ldquo \"“\"><!ENTITY rdquo \"”\"><!ENTITY bdquo \"„\"><!ENTITY dagger \"†\"><!ENTITY Dagger \"‡\"><!ENTITY permil \"‰\"><!ENTITY lsaquo \"‹\"><!ENTITY rsaquo \"›\"><!ENTITY euro \"€\">\n]>\n" + html;
return new String(html.getBytes(), "GB2312");
}
/**
* 格式化html
*
* @param element
* @param basePath
* @throws Exception
*/
public void convertReportHtml(org.jsoup.nodes.Element element, String basePath) throws Exception {
if (element.id().equals("customerImg")) {
element.remove();
return;
}
String tagName = element.tagName();
if (tagName.equals("table") && !"printTable".equals(element.id())) { //printTable 是需求版本输出Word时,用于布局的表格,不应该显示边框
String style = element.attr("style");
style += "width: 100%; border:1px solid #CCC; border-collapse:collapse;";
element.attr("style", style);
} else if (tagName.equals("th") && !"printTable".equals(element.parent().parent().parent().id())) {
String style = element.attr("style");
style += " border:1px solid #CCC;";
element.attr("style", style);
} else if (tagName.equals("td") && !"printTable".equals(element.parent().parent().parent().id())) {
String style = element.attr("style");
style += " border:1px solid #EEE;";
element.attr("style", style);
} else if (tagName.equals("img")) {
String src = element.attr("src");
if (!src.startsWith("http")) {
src = basePath + src;
element.attr("src", src);
}
if (src.contains("svg") && src.contains("version")) {//如果highchart图表,先删除掉
element.remove();
return;
}
} else if (tagName.equals("a")) {
String href = element.attr("href");
if (!href.startsWith("http")) {
href = basePath + href;
element.attr("href", href);
}
}
Elements elements = element.children();
if (elements.isEmpty()) {
return;
}
for (org.jsoup.nodes.Element e : elements) {
convertReportHtml(e, basePath);
}
}
/**
* 将html转成段落
*/
public void html2WordWithParagram(String htmlContent, String basePath) throws Exception {
org.jsoup.nodes.Document document = Jsoup.parse(htmlContent, basePath);
convertReportHtml(document, basePath);
String html = document.toString();
html = setHTMLHead(html);
RPr rpr = getRPr("宋体", "000000", "22",
STHint.EAST_ASIA, false, false, false, false);
P p = factory.createP();
setParagraphSpacing(p, JcEnumeration.CENTER, true, "100", "100", null,
null, true, "240", STLineSpacingRule.AUTO);
R run = factory.createR();
// 设置表格内容字体样式
run.setRPr(rpr);
XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);
run.getContent().addAll(XHTMLImporter.convert(html, null));
p.getContent().add(run);
mp.addObject(p);
}
/**
* 将html生成文档
*/
public void html2WordWithDocument(String html) throws Exception {
XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);
wordMLPackage.getMainDocumentPart().getContent().addAll(
XHTMLImporter.convert(html, null));
}
/**
* 写标题或段落
*/
public void addParagraph(String txtValue, boolean isTitle, int fontSize, boolean isBlod) throws Exception {
RPr rpr;
JcEnumeration jcEnumeration;
if (isTitle) {
rpr = getRPr("微软雅黑", "000000", fontSize + "", STHint.EAST_ASIA,
isBlod, false, false, false);
jcEnumeration = JcEnumeration.CENTER;
} else {
rpr = getRPr("宋体", "000000", fontSize + "", STHint.EAST_ASIA,
isBlod, false, false, false);
jcEnumeration = JcEnumeration.LEFT;
}
Text txt = factory.createText();
txt.setValue(txtValue);
R run = factory.createR();
run.getContent().add(txt);
run.setRPr(rpr);
P paragraph = factory.createP();
paragraph.getContent().add(run);
setParagraphSpacing(paragraph, jcEnumeration, true,
"0", "0", null, null, true, "240", STLineSpacingRule.AUTO);
mp.addObject(paragraph);
}
/**
* 根据等级设置字体
*
* @param level
*/
public RPr getRPrByHeadLevel(int level) {
int fontSize = 30 - level;
RPr rpr = getRPr("宋体", "000000", fontSize + "", STHint.EAST_ASIA,
level <= 1, false, false, false);
return rpr;
}
/**
* 添加段落
*
* @param paragraph
* @throws Exception
*/
public void addParagraph(P paragraph) throws Exception {
mp.addObject(paragraph);
}
/**
* 分割线
*/
public void createLine() {
addPageBreak(STBrType.TEXT_WRAPPING);
CTBorder topBorder = new CTBorder();
topBorder.setSpace(new BigInteger("1"));
topBorder.setSz(new BigInteger("1"));
topBorder.setVal(STBorder.SINGLE);
P p = factory.createP();
PPr ppr = new PPr();
PPrBase.PBdr pBdr = new PPrBase.PBdr();
pBdr.setTop(topBorder);
ppr.setPBdr(pBdr);
p.setPPr(ppr);
mp.addObject(p);
}
// 设置段间距-->行距 段前段后距离
// 段前段后可以设置行和磅 行距只有磅
// 段前磅值和行值同时设置,只有行值起作用
// TODO 1磅=20 1行=100 单倍行距=240 为什么是这个值不知道
/**
* @param jcEnumeration 对齐方式
* @param isSpace 是否设置段前段后值
* @param before 段前磅数
* @param after 段后磅数
* @param beforeLines 段前行数
* @param afterLines 段后行数
* @param isLine 是否设置行距
* @param lineValue 行距值
* @param sTLineSpacingRule 自动auto 固定exact 最小 atLeast
*/
public void setParagraphSpacing(P p, JcEnumeration jcEnumeration, boolean isSpace, String before, String after,
String beforeLines, String afterLines, boolean isLine, String lineValue, STLineSpacingRule sTLineSpacingRule) {
PPr pPr = p.getPPr();
if (pPr == null) {
pPr = factory.createPPr();
}
Jc jc = pPr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
pPr.setJc(jc);
PPrBase.Spacing spacing = new PPrBase.Spacing();
if (isSpace) {
if (before != null) {
// 段前磅数
spacing.setBefore(new BigInteger(before));
}
if (after != null) {
// 段后磅数
spacing.setAfter(new BigInteger(after));
}
if (beforeLines != null) {
// 段前行数
spacing.setBeforeLines(new BigInteger(beforeLines));
}
if (afterLines != null) {
// 段后行数
spacing.setAfterLines(new BigInteger(afterLines));
}
}
if (isLine) {
if (lineValue != null) {
spacing.setLine(new BigInteger(lineValue));
}
spacing.setLineRule(sTLineSpacingRule);
}
pPr.setSpacing(spacing);
p.setPPr(pPr);
}
/**
* 创建字体
*
* @param isBlod 粗体
* @param isUnderLine 下划线
* @param isItalic 斜体
* @param isStrike 删除线
*/
public RPr getRPr(String fontFamily, String colorVal, String fontSize, STHint sTHint, boolean isBlod,
boolean isUnderLine, boolean isItalic, boolean isStrike) {
RPr rPr = factory.createRPr();
RFonts rf = new RFonts();
rf.setHint(sTHint);
rf.setAscii(fontFamily);
rf.setHAnsi(fontFamily);
rPr.setRFonts(rf);
BooleanDefaultTrue bdt = factory.createBooleanDefaultTrue();
rPr.setBCs(bdt);
if (isBlod) {
rPr.setB(bdt);
}
if (isItalic) {
rPr.setI(bdt);
}
if (isStrike) {
rPr.setStrike(bdt);
}
if (isUnderLine) {
U underline = new U();
underline.setVal(UnderlineEnumeration.SINGLE);
rPr.setU(underline);
}
Color color = new Color();
color.setVal(colorVal);
rPr.setColor(color);
HpsMeasure sz = new HpsMeasure();
sz.setVal(new BigInteger(fontSize));
rPr.setSz(sz);
rPr.setSzCs(sz);
return rPr;
}
// 分页
public void addPageBreak(STBrType sTBrType) {
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Br breakObj = new Br();
breakObj.setType(sTBrType);
P paragraph = factory.createP();
paragraph.getContent().add(breakObj);
documentPart.addObject(paragraph);
}
// 得到页面宽度
public int getWritableWidth()
throws Exception {
return wordMLPackage.getDocumentModel().getSections().get(0)
.getPageDimensions().getWritableWidthTwips();
}
/**
* 表格占页面宽度
*/
public void setTableGridCol(Tbl table, int colSize) throws Exception {
TblGrid tblGrid = factory.createTblGrid();
for (int i = 0; i < colSize; i++) {
TblGridCol gridCol = factory.createTblGridCol();
gridCol.setW(BigInteger.valueOf(2256));
tblGrid.getGridCol().add(gridCol);
}
table.setTblGrid(tblGrid);
TblPr tblPr = table.getTblPr();
if (tblPr == null) {
tblPr = factory.createTblPr();
}
TblWidth tblWidth = new TblWidth();
tblWidth.setType("dxa");// 这一行是必须的,不自己设置宽度默认是auto
tblWidth.setW(new BigInteger("9027"));
tblPr.setTblW(tblWidth);
table.setTblPr(tblPr);
}
// 表格水平对齐方式
public void setTableAlign(Tbl table,
JcEnumeration jcEnumeration) {
TblPr tablePr = table.getTblPr();
if (tablePr == null) {
tablePr = factory.createTblPr();
}
Jc jc = tablePr.getJc();
if (jc == null) {
jc = new Jc();
}
jc.setVal(jcEnumeration);
tablePr.setJc(jc);
table.setTblPr(tablePr);
}
// 表格增加边框 可以设置上下左右四个边框样式以及横竖水平线样式
public void addBorders(Tbl table, CTBorder topBorder, CTBorder bottomBorder, CTBorder leftBorder, CTBorder rightBorder,
CTBorder hBorder, CTBorder vBorder) {
table.setTblPr(new TblPr());
TblBorders borders = new TblBorders();
borders.setBottom(bottomBorder);
borders.setLeft(leftBorder);
borders.setRight(rightBorder);
borders.setTop(topBorder);
borders.setInsideH(hBorder);
borders.setInsideV(vBorder);
table.getTblPr().setTblBorders(borders);
}
public void mergeCellsHorizontalByGridSpan(Tbl tbl, int row, int fromCell,
int toCell) {
if (row < 0 || fromCell < 0 || toCell < 0) {
return;
}
List<Tr> trList = getTblAllTr(tbl);
if (row > trList.size()) {
return;
}
Tr tr = trList.get(row);
List<Tc> tcList = getTrAllCell(tr);
for (int cellIndex = Math.min(tcList.size() - 1, toCell); cellIndex >= fromCell; cellIndex--) {
Tc tc = tcList.get(cellIndex);
TcPr tcPr = getTcPr(tc);
if (cellIndex == fromCell) {
TcPrInner.GridSpan gridSpan = tcPr.getGridSpan();
if (gridSpan == null) {
gridSpan = new TcPrInner.GridSpan();
tcPr.setGridSpan(gridSpan);
}
gridSpan.setVal(BigInteger.valueOf(Math.min(tcList.size() - 1,
toCell) - fromCell + 1));
} else {
tr.getContent().remove(cellIndex);
}
}
}
/**
* 跨列合并
*/
public void mergeCellsHorizontal(Tbl tbl, int row, int fromCell, int toCell, TblWidth tblWidth) {
if (row < 0 || fromCell < 0 || toCell < 0) {
return;
}
List<Tr> trList = getTblAllTr(tbl);
if (row > trList.size()) {
return;
}
Tr tr = trList.get(row);
List<Tc> tcList = getTrAllCell(tr);
Tc cell = tcList.get(0);
TcPr cellPr = getTcPr(cell);
cellPr.setTcW(tblWidth);
for (int cellIndex = fromCell, len = Math
.min(tcList.size() - 1, toCell); cellIndex <= len; cellIndex++) {
Tc tc = tcList.get(cellIndex);
TcPr tcPr = getTcPr(tc);
TcPrInner.HMerge hMerge = tcPr.getHMerge();
if (hMerge == null) {
hMerge = new TcPrInner.HMerge();
tcPr.setHMerge(hMerge);
}
if (cellIndex == fromCell) {
hMerge.setVal("restart");
} else {
hMerge.setVal("continue");
}
}
}
/**
* 跨行合并
*/
public void mergeCellsVertically(Tbl tbl, int col, int fromRow, int toRow) {
if (col < 0 || fromRow < 0 || toRow < 0) {
return;
}
for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
Tc tc = getTc(tbl, rowIndex, col);
if (tc == null) {
break;
}
TcPr tcPr = getTcPr(tc);
TcPrInner.VMerge vMerge = tcPr.getVMerge();
if (vMerge == null) {
vMerge = new TcPrInner.VMerge();
tcPr.setVMerge(vMerge);
}
if (rowIndex == fromRow) {
vMerge.setVal("restart");
} else {
vMerge.setVal("continue");
}
}
}
/**
* 得到指定位置的表格
*/
public Tc getTc(Tbl tbl, int row, int cell) {
if (row < 0 || cell < 0) {
return null;
}
List<Tr> trList = getTblAllTr(tbl);
if (row >= trList.size()) {
return null;
}
List<Tc> tcList = getTrAllCell(trList.get(row));
if (cell >= tcList.size()) {
return null;
}
return tcList.get(cell);
}
/**
* 获取所有的单元格
*/
public List<Tc> getTrAllCell(Tr tr) {
List<Object> objList = getAllElementFromObject(tr, Tc.class);
List<Tc> tcList = new ArrayList<Tc>();
if (objList == null) {
return tcList;
}
for (Object tcObj : objList) {
if (tcObj instanceof Tc) {
Tc objTc = (Tc) tcObj;
tcList.add(objTc);
}
}
return tcList;
}
public static TcPr getTcPr(Tc tc) {
TcPr tcPr = tc.getTcPr();
if (tcPr == null) {
tcPr = new TcPr();
tc.setTcPr(tcPr);
}
return tcPr;
}
/**
* 得到表格所有的行
*/
public List<Tr> getTblAllTr(Tbl tbl) {
List<Object> objList = getAllElementFromObject(tbl, Tr.class);
List<Tr> trList = new ArrayList<Tr>();
if (objList == null) {
return trList;
}
for (Object obj : objList) {
if (obj instanceof Tr) {
Tr tr = (Tr) obj;
trList.add(tr);
}
}
return trList;
}
/**
* 得到指定类型的元素
*/
public List<Object> getAllElementFromObject(Object obj,
Class<?> toSearch) {
List<Object> result = new ArrayList<Object>();
if (obj instanceof JAXBElement)
obj = ((JAXBElement<?>) obj).getValue();
if (obj.getClass().equals(toSearch))
result.add(obj);
else if (obj instanceof ContentAccessor) {
List<?> children = ((ContentAccessor) obj).getContent();
for (Object child : children) {
result.addAll(getAllElementFromObject(child, toSearch));
}
}
return result;
}
/**
* 栏目内容(表格)
*/
public void createNormalTable(List<String[]> tableValue, String basePath) throws Exception {
RPr titleRpr = getRPr("宋体", "000000", "22", STHint.EAST_ASIA,
true, false, false, false);
RPr contentRpr = getRPr("宋体", "000000", "22",
STHint.EAST_ASIA, false, false, false, false);
Tbl table = factory.createTbl();
CTBorder topBorder = new CTBorder();
topBorder.setVal(STBorder.DOUBLE);
topBorder.setSz(new BigInteger("2"));
CTBorder leftBorder = new CTBorder();
leftBorder.setVal(STBorder.NONE);
leftBorder.setSz(new BigInteger("0"));
CTBorder hBorder = new CTBorder();
hBorder.setVal(STBorder.SINGLE);
hBorder.setSz(new BigInteger("1"));
addBorders(table, topBorder, topBorder, leftBorder, leftBorder, hBorder, null);
setTableGridCol(table, 4);
String[] colorStr = new String[]{"E3E3E3", "D3D3D3"};
for (int i = 0; i < tableValue.size(); i++) {
String[] trValue = tableValue.get(i);
Tr contentRow = factory.createTr();
addTableCell(contentRow, StringUtils.isNotBlank(trValue[0]) ? trValue[0] : "", titleRpr,
JcEnumeration.CENTER, true, colorStr[i % 2], basePath);
addTableCell(contentRow, StringUtils.isNotBlank(trValue[1]) ? trValue[1] : "", contentRpr,
JcEnumeration.LEFT, true, colorStr[i % 2], basePath);
addTableCell(contentRow, StringUtils.isNotBlank(trValue[2]) ? trValue[2] : "", titleRpr,
JcEnumeration.CENTER, true, colorStr[i % 2], basePath);
addTableCell(contentRow, StringUtils.isNotBlank(trValue[3]) ? trValue[3] : "", contentRpr,
JcEnumeration.LEFT, true, colorStr[i % 2], basePath);
table.getContent().add(contentRow);
if (!StringUtils.isNotBlank(trValue[2])) {//需要合并
TblWidth tblWidth = new TblWidth();
tblWidth.setType("dxa");
tblWidth.setW(new BigInteger("2256"));
mergeCellsHorizontal(table, i, 1, 3, tblWidth);
}
}
setTableAlign(table, JcEnumeration.CENTER);
mp.addObject(table);
}
/**
* 栏目
*
* @param titleColumnName
* @throws Exception
*/
public void createTitleColumn(String titleColumnName) throws Exception {
RPr boldRPr = getRPr("宋体", "000000", "24", STHint.EAST_ASIA,
true, false, false, false);
ObjectFactory factory = getFactory();
P paragraph = factory.createP();
Text txt = factory.createText();
txt.setValue(titleColumnName);
R run = factory.createR();
run.getContent().add(txt);
run.setRPr(boldRPr);
paragraph.getContent().add(run);
setParagraphSpacing(paragraph, JcEnumeration.LEFT, true, "0",
"0", "200", "100", true, "240", STLineSpacingRule.AUTO);
mp.addObject(paragraph);
}
// 新增单元格
private void addTableCell(Tr tableRow, String content,
RPr rpr, JcEnumeration jcEnumeration, boolean hasBgColor,
String backgroudColor, String basePath) throws Exception {
Tc tableCell = factory.createTc();
P p = factory.createP();
setParagraphSpacing(p, jcEnumeration, true, "100", "100", null,
null, true, "240", STLineSpacingRule.AUTO);
TcPr tcPr = tableCell.getTcPr();
if (tcPr == null) {
tcPr = factory.createTcPr();
}
CTVerticalJc valign = factory.createCTVerticalJc();
valign.setVal(STVerticalJc.CENTER);
tcPr.setVAlign(valign);
R run = factory.createR();
// 设置表格内容字体样式
run.setRPr(rpr);
//写值
if (content.endsWith("##$html$##")) {
content = content.replace("##$html$##", "");
content = content.replace(" ", " ");
if (content.contains("servlet/image?f=")) {
content = content.replace("servlet/image?f=", basePath + "servlet/image?f=");
}
XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);
run.getContent().addAll(XHTMLImporter.convert("<div>" + content + "</div>", null));
p.getContent().add(run);
tableCell.getContent().add(p);
} else {
Text t = factory.createText();
t.setValue(content);
run.getContent().add(t);
p.getContent().add(run);
tableCell.getContent().add(p);
}
if (hasBgColor) {
CTShd shd = tcPr.getShd();
if (shd == null) {
shd = factory.createCTShd();
}
shd.setColor("auto");
shd.setFill(backgroudColor);
tcPr.setShd(shd);
}
tableCell.setTcPr(tcPr);
tableRow.getContent().add(tableCell);
}
}
以上是公用方法,简单使用
//html转word
public void exportFormatItemPage(String content, String basePath) throws Exception {
//创建文档
Docx4jWord word = Docx4jWord.createWord();
org.jsoup.nodes.Document document = Jsoup.parse(content, basePath);
word.convertReportHtml(document, basePath);
String html = document.toString();
html = word.setHTMLHead(html);
//html转word
word.html2WordWithDocument(html);
WordprocessingMLPackage wordMLPackage = word.getWordMLPackage();;
wordMLPackage.save(outputStream());
}
//写word
public WordprocessingMLPackage exportWordByDoc4j(String basePath, ViewFormatItemInformation info, List<PageColumnConfigBean> colums,
String tagPrefix, String docTypeName, String docName) throws Exception{
//创建文档
Docx4jWord word = Docx4jWord.createWord();
//写标题
word.addParagraph(docTypeName + "-详细信息", true, 34, true);
word.addParagraph("所属文档《" + docName + "》", true, 22, false);
//读内容
String colName = "";
List<List<PageColumnConfigBean>> content = new ArrayList<>();//记录栏目内属性
List<String> columNames = new ArrayList<>();//记录栏目
for (int i = 0; i < colums.size(); i++) {
PageColumnConfigBean colum = colums.get(i);
//栏目
if (colum.getPojoName() == null && colum.getTitle() != null) {
colName = colum.getTitle();
columNames.add(colName);
List<PageColumnConfigBean> list = new ArrayList<>();
content.add(list);
} else {//属性
List<PageColumnConfigBean> list = content.get(content.size() - 1);
list.add(colum);
}
}
for (int i = 0; i < columNames.size(); i++) {
//写栏目
word.createTitleColumn(columNames.get(i));
//写栏目属性
if (content.get(i).size() > 0) {
List<String[]> table = getTableValuesByColums( content.get(i), info, tagPrefix);
word.createNormalTable(table, basePath);
}
}
return word.getWordMLPackage();
}
特殊字符声明头:
<!ENTITY iexcl "¡"><!ENTITY cent "¢"><!ENTITY pound "£"><!ENTITY curren "¤"><!ENTITY yen "¥"><!ENTITY brvbar "¦"><!ENTITY sect "§"><!ENTITY uml "¨"><!ENTITY copy "©"><!ENTITY ordf "ª"><!ENTITY laquo "«"><!ENTITY not "¬"><!ENTITY shy ""><!ENTITY reg "®"><!ENTITY macr "¯"><!ENTITY deg "°"><!ENTITY plusmn "±"><!ENTITY sup2 "²"><!ENTITY sup3 "³"><!ENTITY acute "´"><!ENTITY micro "µ"><!ENTITY para "¶"><!ENTITY middot "·"><!ENTITY cedil "¸"><!ENTITY sup1 "¹"><!ENTITY ordm "º"><!ENTITY raquo "»"><!ENTITY frac14 "¼"><!ENTITY frac12 "½"><!ENTITY frac34 "¾"><!ENTITY iquest "¿"><!ENTITY Agrave "À"><!ENTITY Aacute "Á"><!ENTITY Acirc "Â"><!ENTITY Atilde "Ã"><!ENTITY Auml "Ä"><!ENTITY Aring "Å"><!ENTITY AElig "Æ"><!ENTITY Ccedil "Ç"><!ENTITY Egrave "È"><!ENTITY Eacute "É"><!ENTITY Ecirc "Ê"><!ENTITY Euml "Ë"><!ENTITY Igrave "Ì"><!ENTITY Iacute "Í"><!ENTITY Icirc "Î"><!ENTITY Iuml "Ï"><!ENTITY ETH "Ð"><!ENTITY Ntilde "Ñ"><!ENTITY Ograve "Ò"><!ENTITY Oacute "Ó"><!ENTITY Ocirc "Ô"><!ENTITY Otilde "Õ"><!ENTITY Ouml "Ö"><!ENTITY times "×"><!ENTITY Oslash "Ø"><!ENTITY Ugrave "Ù"><!ENTITY Uacute "Ú"><!ENTITY Ucirc "Û"><!ENTITY Uuml "Ü"><!ENTITY Yacute "Ý"><!ENTITY THORN "Þ"><!ENTITY szlig "ß"><!ENTITY agrave "à"><!ENTITY aacute "á"><!ENTITY acirc "â"><!ENTITY atilde "ã"><!ENTITY auml "ä"><!ENTITY aring "å"><!ENTITY aelig "æ"><!ENTITY ccedil "ç"><!ENTITY egrave "è"><!ENTITY eacute "é"><!ENTITY ecirc "ê"><!ENTITY euml "ë"><!ENTITY igrave "ì"><!ENTITY iacute "í"><!ENTITY icirc "î"><!ENTITY iuml "ï"><!ENTITY eth "ð"><!ENTITY ntilde "ñ"><!ENTITY ograve "ò"><!ENTITY oacute "ó"><!ENTITY ocirc "ô"><!ENTITY otilde "õ"><!ENTITY ouml "ö"><!ENTITY divide "÷"><!ENTITY oslash "ø"><!ENTITY ugrave "ù"><!ENTITY uacute "ú"><!ENTITY ucirc "û"><!ENTITY uuml "ü"><!ENTITY yacute "ý"><!ENTITY thorn "þ"><!ENTITY yuml "ÿ"><!ENTITY fnof "ƒ"><!ENTITY Alpha "Α"><!ENTITY Beta "Β"><!ENTITY Gamma "Γ"><!ENTITY Delta "Δ"><!ENTITY Epsilon "Ε"><!ENTITY Zeta "Ζ"><!ENTITY Eta "Η"><!ENTITY Theta "Θ"><!ENTITY Iota "Ι"><!ENTITY Kappa "Κ"><!ENTITY Lambda "Λ"><!ENTITY Mu "Μ"><!ENTITY Nu "Ν"><!ENTITY Xi "Ξ"><!ENTITY Omicron "Ο"><!ENTITY Pi "Π"><!ENTITY Rho "Ρ"><!ENTITY Sigma "Σ"><!ENTITY Tau "Τ"><!ENTITY Upsilon "Υ"><!ENTITY Phi "Φ"><!ENTITY Chi "Χ"><!ENTITY Psi "Ψ"><!ENTITY Omega "Ω"><!ENTITY alpha "α"><!ENTITY beta "β"><!ENTITY gamma "γ"><!ENTITY delta "δ"><!ENTITY epsilon "ε"><!ENTITY zeta "ζ"><!ENTITY eta "η"><!ENTITY theta "θ"><!ENTITY iota "ι"><!ENTITY kappa "κ"><!ENTITY lambda "λ"><!ENTITY mu "μ"><!ENTITY nu "ν"><!ENTITY xi "ξ"><!ENTITY omicron "ο"><!ENTITY pi "π"><!ENTITY rho "ρ"><!ENTITY sigmaf "ς"><!ENTITY sigma "σ"><!ENTITY tau "τ"><!ENTITY upsilon "υ"><!ENTITY phi "φ"><!ENTITY chi "χ"><!ENTITY psi "ψ"><!ENTITY omega "ω"><!ENTITY thetasym "ϑ"><!ENTITY upsih "ϒ"><!ENTITY piv "ϖ"><!ENTITY bull "•"><!ENTITY hellip "…"><!ENTITY prime "′"><!ENTITY Prime "″"><!ENTITY oline "‾"><!ENTITY frasl "⁄"><!ENTITY weierp "℘"><!ENTITY image "ℑ"><!ENTITY real "ℜ"><!ENTITY trade "™"><!ENTITY alefsym "ℵ"><!ENTITY larr "←"><!ENTITY uarr "↑"><!ENTITY rarr "→"><!ENTITY darr "↓"><!ENTITY harr "↔"><!ENTITY crarr "↵"><!ENTITY lArr "⇐"><!ENTITY uArr "⇑"><!ENTITY rArr "⇒"><!ENTITY dArr "⇓"><!ENTITY hArr "⇔"><!ENTITY forall "∀"><!ENTITY part "∂"><!ENTITY exist "∃"><!ENTITY empty "∅"><!ENTITY nabla "∇"><!ENTITY isin "∈"><!ENTITY notin "∉"><!ENTITY ni "∋"><!ENTITY prod "∏"><!ENTITY sum "∑"><!ENTITY minus "−"><!ENTITY lowast "∗"><!ENTITY radic "√"><!ENTITY prop "∝"><!ENTITY infin "∞"><!ENTITY ang "∠"><!ENTITY and "∧"><!ENTITY or "∨"><!ENTITY cap "∩"><!ENTITY cup "∪"><!ENTITY int "∫"><!ENTITY there4 "∴"><!ENTITY sim "∼"><!ENTITY cong "≅"><!ENTITY asymp "≈"><!ENTITY ne "≠"><!ENTITY equiv "≡"><!ENTITY le "≤"><!ENTITY ge "≥"><!ENTITY sub "⊂"><!ENTITY sup "⊃"><!ENTITY nsub "⊄"><!ENTITY sube "⊆"><!ENTITY supe "⊇"><!ENTITY oplus "⊕"><!ENTITY otimes "⊗"><!ENTITY perp "⊥"><!ENTITY sdot "⋅"><!ENTITY lceil "⌈"><!ENTITY rceil "⌉"><!ENTITY lfloor "⌊"><!ENTITY rfloor "⌋"><!ENTITY lang "〈"><!ENTITY rang "〉"><!ENTITY loz "◊"><!ENTITY spades "♠"><!ENTITY clubs "♣"><!ENTITY hearts "♥"><!ENTITY diams "♦"><!ENTITY quot """><!ENTITY amp "&"><!ENTITY lt "<"><!ENTITY gt ">"><!ENTITY OElig "Œ"><!ENTITY oelig "œ"><!ENTITY Scaron "Š"><!ENTITY scaron "š"><!ENTITY Yuml "Ÿ"><!ENTITY circ "ˆ"><!ENTITY tilde "˜"><!ENTITY ensp " "><!ENTITY emsp " "><!ENTITY thinsp " "><!ENTITY zwnj ""><!ENTITY zwj ""><!ENTITY lrm ""><!ENTITY rlm ""><!ENTITY ndash "–"><!ENTITY mdash "—"><!ENTITY lsquo "‘"><!ENTITY rsquo "’"><!ENTITY sbquo "‚"><!ENTITY ldquo "“"><!ENTITY rdquo "”"><!ENTITY bdquo "„"><!ENTITY dagger "†"><!ENTITY Dagger "‡"><!ENTITY permil "‰"><!ENTITY lsaquo "‹"><!ENTITY rsaquo "›"><!ENTITY euro "€">]>