使用docx4j生成数据库字典文档
文本参考文章
https://www.cnblogs.com/qlqwjy/p/9866484.html
1.引入docx4j
本案例使用maven仓库引入jar包
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.1.2</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<!-- JSON插件 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
2.docx4j配置
可以不添加配置文件,但debug日志会提示找不到docx4j配置文件
在src下创建docx4j.properties配置文件,maven项目请放在resources文件夹下
# Page size: use a value from org.docx4j.model.structure.PageSizePaper enum
# eg A4, LETTER
docx4j.PageSize=LETTER
# Page size: use a value from org.docx4j.model.structure.MarginsWellKnown enum
docx4j.PageMargins=NORMAL
docx4j.PageOrientationLandscape=false
# Page size: use a value from org.pptx4j.model.SlideSizesWellKnown enum
# eg A4, LETTER
pptx4j.PageSize=LETTER
pptx4j.PageOrientationLandscape=false
# These will be injected into docProps/app.xml
# if App.Write=true
docx4j.App.write=true
docx4j.Application=docx4j
docx4j.AppVersion=6.1.2
# of the form XX.YYYY where X and Y represent numerical values
# These will be injected into docProps/core.xml
docx4j.dc.write=true
docx4j.dc.creator.value=docx4j
docx4j.dc.lastModifiedBy.value=docx4j
#
#docx4j.McPreprocessor=true
# If you haven't configured log4j yourself
# docx4j will autoconfigure it. Set this to true to disable that
docx4j.Log4j.Configurator.disabled=false
3.生成数据字典.docx
public static void main(String[] args) throws Exception{
String templateFilePath = "template.docx";
String wordFilePath = "数据字典.docx";
HashMap<String, String> params = new HashMap<>();
params.put("system_name", "xxx系統");
params.put("title", "數據字典");
params.put("author", "test");
params.put("date", "2021-03-21");
// 数据字典
DataDict dataDict = mockData();
// 创建word
WordprocessingMLPackage wordMLPackage = Docx4jUtils.load(templateFilePath);
// 写入数据清单
writeTableDict(wordMLPackage, dataDict);
// 写入数据明细
writeTableDetail(wordMLPackage, dataDict);
// 参数替换
Docx4jUtils.variableReplace(wordMLPackage, params);
// 写入目录
writeToc(wordMLPackage);
// save
Docx4jUtils.save(wordMLPackage, wordFilePath);
}
/**
* 写入数据清单
*/
private static void writeTableDict(WordprocessingMLPackage wordMLPackage, DataDict dataDict) throws Exception{
// 查找table
ClassFinder find = new ClassFinder(Tbl.class);
new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), find);
//获取到第三个表格元素=数据清单
Tbl table = (Tbl) find.results.get(2);
// 第二行约定为模板,获取到第二行内容
Tr dynamicTr = (Tr) table.getContent().get(1);
// 获取模板行的xml数据
String dynamicTrXml = XmlUtils.marshaltoString(dynamicTr);
// 替换数据
LinkedHashMap<String, String> map;
for(UserTable userTable : dataDict.getUserTables()){
map = new LinkedHashMap<>();
map.put("table_name", userTable.getTableName());
map.put("table_comment", userTable.getComments());
// 填充模板行数据
Tr newTr = (Tr) XmlUtils.unmarshallFromTemplate(dynamicTrXml, map);
table.getContent().add(newTr);
}
// 删除模板行的占位行
table.getContent().remove(1);
}
/**
* 写入数据表明细
*/
private final static String TITLE = "2.%s %s %s";
private static void writeTableDetail(WordprocessingMLPackage wordMLPackage, DataDict dataDict){
// 提取正文
MainDocumentPart main = wordMLPackage.getMainDocumentPart();
ObjectFactory factory = Context.getWmlObjectFactory();
// 数据表
List<UserTable> userTables = dataDict.getUserTables();
List<String> primaryKeys = new ArrayList<>();
for(int i=0; i<userTables.size(); i++){
UserTable userTable = userTables.get(i);
// 设置标题
// styleId=3为标题2
main.addStyledParagraphOfText("3", String.format(TITLE, (i+1), userTable.getTableName(), userTable.getComments()));
// 创建表格
Tbl table = factory.createTbl();
// 必须设置一个TblPr,否则最后会报空指针异常
table.setTblPr(new TblPr());
// 设置表格边框样式
// 设置表格边框样式
TableBorderStyle borderStyle = new TableBorderStyle();
borderStyle.setColor("auto");
borderStyle.setSize(new BigInteger("4"));
borderStyle.setSpace(new BigInteger("0"));
borderStyle.setStyle(STBorder.SINGLE);
CTBorder ctBorder = Docx4jUtils.buildTableBorder(borderStyle);
TblBorders tblBorders = Docx4jUtils.setTableBorder(ctBorder,ctBorder,ctBorder,ctBorder);
table.getTblPr().setTblBorders(tblBorders);
table.getTblPr().setTblW(Docx4jUtils.buildTblWidth(BigInteger.valueOf(5000)));
// 写入标题
addTableTitle(factory, table);
// 字段信息
List<UserTabColumn> userTabColumns = dataDict.getUserTabColumns().get(userTable.getTableName());
for(UserTabColumn userTabColumn : userTabColumns){
// 创建行
Tr tr = factory.createTr();
String columnName = userTabColumn.getColumnName();
List<UserColComment> userColComments = dataDict.getUserColComment().get(userTable.getTableName() + columnName);
String columnComment = userColComments.get(0).getComments();
String dataType = userTabColumn.getDataType();
switch (dataType){
case "NCLOB":
dataType = "CLOB";
break;
case "NBLOB":
dataType = "BLOB";
break;
case "NVARCHAR2":
dataType = "VARCHAR2";
break;
}
if (!("CLOB".equals(dataType) || "BLOB".equals(dataType) || "NUMBER".equals(dataType))) {
dataType = String.format("%s(%s)", dataType, userTabColumn.getDataLength());
} else if ("NUMBER".equals(dataType)) {
dataType = String.format("%s(%s,%s)",dataType,userTabColumn.getDataPrecision(),userTabColumn.getDataScale());
}
String notNull = "TRUE";
if ("NO".equals(userTabColumn.getDefaultOnNull())) {
notNull = "FALSE";
}
tr.getContent().add(buildTableRow(factory, columnName,1000));
tr.getContent().add(buildTableRow(factory, dataType,1000));
tr.getContent().add(buildTableRow(factory, notNull,1000));
tr.getContent().add(buildTableRow(factory, columnComment,2000));
table.getContent().add(tr);
}
// 索引信息
List<String> idxData = new ArrayList<>();
// 主键索引信息
primaryKeys.clear();
List<UserConstraint> userConstraints = dataDict.getUserConstraints().get(userTable.getTableName());
if(null != userConstraints && userConstraints.size() > 0){
for(UserConstraint userConstraint : userConstraints){
primaryKeys.add(userConstraint.getIndexName());
List<UserIndColumn> userIndColumns = dataDict.getUserIndColumns().get(userConstraint.getTableName() + userConstraint.getIndexName());
StringBuilder pkCols = new StringBuilder();
for(UserIndColumn userIndColumn : userIndColumns){
pkCols.append("\"").append(userIndColumn.getColumnName()).append("\",");
}
idxData.add("主键: " + userConstraint.getIndexName() + "(" + pkCols.substring(0, pkCols.length()-1) + ")");
}
}
// 非主键索引
List<UserIndex> userIndices = dataDict.getUserIndexes().get(userTable.getTableName());
if(null != userIndices && userIndices.size() > 0){
for(UserIndex userIndex : userIndices){
if (primaryKeys.contains(userIndex.getIndexName())) {
continue;
}
List<UserIndColumn> userIndColumns = dataDict.getUserIndColumns().get(userIndex.getTableName() + userIndex.getIndexName());
if(null == userIndColumns || userIndColumns.size() == 0){
continue;
}
StringBuilder stb = new StringBuilder();
boolean flag = false;
for (UserIndColumn userIndColumn : userIndColumns) {
if (userIndex.getIndexName().equals(userIndColumn.getIndexName())) {
stb.append("\"").append(userIndColumn.getColumnName()).append("\",");
flag = true;
}
}
if (flag) {
String uniqueness = "NONUNIQUE".equals(userIndex.getUniqueness()) ? "索引" : "唯一索引";
idxData.add(String.format("%s: %s(%s)", uniqueness, userIndex.getIndexName(), stb.substring(0, stb.length() -1)));
}
}
}
// 新增索引信息
addTableIndex(factory, table, idxData, BigInteger.valueOf(5000));
// 加表格加到主要内容中
main.addObject(table);
}
}
/**
* 新增表格标题
*/
private static void addTableTitle(ObjectFactory factory, Tbl table){
Tr tr = factory.createTr();
tr.getContent().add(buildTableTitle(factory, "字段名稱", 1000));
tr.getContent().add(buildTableTitle(factory, "字段類型", 1000));
tr.getContent().add(buildTableTitle(factory, "是否強制", 1000));
tr.getContent().add(buildTableTitle(factory, "字段描述", 2000));
table.getContent().add(tr);
}
/**
* 构建表格标题
*/
private static Tc buildTableTitle(ObjectFactory factory, String title, int width){
Tc tc = factory.createTc();
P p = factory.createP();
R r = factory.createR();
// 设置表格标题字体样式
FontStyle tableTitleStyle = new FontStyle();
tableTitleStyle.setSize(BigInteger.valueOf(24));
tableTitleStyle.setBold(true);
RPr rPr = Docx4jUtils.buildFontStyle(factory, tableTitleStyle);
r.setRPr(rPr);
// 内容
Text text = factory.createText();
text.setValue(title);
TcPr tcPr = Docx4jUtils.getTcPr(tc);
// 设置宽度
tcPr.setTcW(Docx4jUtils.buildTblWidth(BigInteger.valueOf(width)));
// 设置背景颜色
CTShd shd = new CTShd();
shd.setVal(STShd.CLEAR);
shd.setColor("auto");
shd.setFill("eeeeee");
tcPr.setShd(shd);
r.getContent().add(text);
p.getContent().add(r);
tc.getContent().add(p);
return tc;
}
/**
* 构建行信息
*/
private static Tc buildTableRow(ObjectFactory factory, String content, int width){
Tc tc = factory.createTc();
P p = factory.createP();
R r = factory.createR();
// 设置字体样式
FontStyle tableContentStyle = new FontStyle();
tableContentStyle.setSize(BigInteger.valueOf(22));
RPr rPr = Docx4jUtils.buildFontStyle(factory, tableContentStyle);
r.setRPr(rPr);
// 内容
Text text = factory.createText();
text.setValue(content);
// 设置宽度
Docx4jUtils.getTcPr(tc).setTcW(Docx4jUtils.buildTblWidth(BigInteger.valueOf(width)));
r.getContent().add(text);
p.getContent().add(r);
tc.getContent().add(p);
return tc;
}
/**
* 新增索引信息
*/
private static void addTableIndex(ObjectFactory factory, Tbl table, List<String> data, BigInteger width){
Tr tr = factory.createTr();
Tc tc = factory.createTc();
// 设置宽度
Docx4jUtils.getTcPr(tc).setTcW(Docx4jUtils.buildTblWidth(width));
for(String item : data){
P p = factory.createP();
R r = factory.createR();
// 设置字体样式
FontStyle tableContentStyle = new FontStyle();
tableContentStyle.setSize(BigInteger.valueOf(22));
RPr rPr = Docx4jUtils.buildFontStyle(factory, tableContentStyle);
r.setRPr(rPr);
// 内容
Text text = factory.createText();
text.setValue(item);
r.getContent().add(text);
p.getContent().add(r);
tc.getContent().add(p);
}
tr.getContent().add(tc);
table.getContent().add(tr);
}
/**
* 写入目录
*/
private static void writeToc(WordprocessingMLPackage wordMLPackage) throws Exception{
// 提取正文
MainDocumentPart main = wordMLPackage.getMainDocumentPart();
List<Object> list = main.getContent();
for(int i=0; i<list.size(); i++){
Object item = list.get(i);
if("目錄".equals(item.toString())){
Docx4jUtils.tocGenerator(wordMLPackage, i, "目錄");
P p = (P)item;
p.getContent().removeAll(p.getContent());
break;
}
}
}
4.模板信息截图
5.生成数据字典截图
6.docx4j相关API
docx格式文档可以理解为一个压缩包,若将其解压可看到一个类似前端的工程项目,其中document.xml用于全文的配置,详细解说请自行查阅资料
创建新的word文档
/**
* 创建新的word文件
*/
public static WordprocessingMLPackage build() throws InvalidFormatException {
return WordprocessingMLPackage.createPackage();
}
读取存在的word文件
/**
* 读取存在的word文件
* @param wordFilePath word文件路径
*/
public static WordprocessingMLPackage load(String wordFilePath) throws Docx4JException{
return WordprocessingMLPackage.load(new File(wordFilePath));
}
保存word文件
/**
* 保存word文件
* @param wordMLPackage word
*/
public static void save(WordprocessingMLPackage wordMLPackage,String wordFilePath) throws Docx4JException {
wordMLPackage.save(new File(wordFilePath));
}
构建字体样式
/**
* 构建字体样式
* @return RPr
*/
public static RPr buildFontStyle(ObjectFactory factory, FontStyle style){
RPr rpr = factory.createRPr();
//设置字体
if(StringUtils.isNotBlank(style.getCnFontFamily()) || StringUtils.isNotBlank(style.getEnFontFamily())){
RFonts font = new RFonts();
font.setAscii(StringUtils.isBlank(style.getCnFontFamily()) ? "宋体" : style.getCnFontFamily());
if(StringUtils.isNotBlank(style.getEnFontFamily())){
font.setEastAsia(style.getEnFontFamily());
}
rpr.setRFonts(font);
}
//设置颜色
if(StringUtils.isNotBlank(style.getColor())){
Color color = new Color();
color.setVal(style.getColor());
rpr.setColor(color);
}
//设置字体大小
if(null != style.getSize()){
HpsMeasure fontSize = new HpsMeasure();
fontSize.setVal(style.getSize());
rpr.setSzCs(fontSize);
rpr.setSz(fontSize);
}
//设置粗体
if(null != style.getBold()){
BooleanDefaultTrue bold = factory.createBooleanDefaultTrue();
bold.setVal(style.getBold());
rpr.setB(bold);
}
//设置斜体
if(null != style.getItalic()){
BooleanDefaultTrue italic = new BooleanDefaultTrue();
rpr.setI(italic);
}
//设置删除线
if(null != style.getDeleteLine()){
BooleanDefaultTrue deleteLine = new BooleanDefaultTrue();
deleteLine.setVal(style.getDeleteLine());
rpr.setStrike(deleteLine);
}
//设置下划线
if(null != style.getUnderlineEnumeration()){
U u = factory.createU();
u.setVal(style.getUnderlineEnumeration());
rpr.setU(u);
}
// 设置背景颜色
if (null != style.getBackgroundColor()) {
CTShd shd = new CTShd();
shd.setVal(style.getBackgroundColor());
rpr.setShd(shd);
}
// 设置边框样式
if(StringUtils.isNotBlank(style.getBorderColor()) || null != style.getBorderSize() || null != style.getBorderSpace()){
CTBorder border = new CTBorder();
if(StringUtils.isNotBlank(style.getBorderColor())){
border.setColor(style.getBorderColor());
}
if(null != style.getBorderSize()){
border.setSz(style.getBorderSize());
}
if(null != style.getBorderSpace()){
border.setSpace(style.getBorderSpace());
}
if(null != style.getBorderShadow()){
border.setShadow(style.getBorderShadow());
}
}
// 着重号
if(null != style.getEmphasis()){
CTEm em = new CTEm();
em.setVal(style.getEmphasis());
rpr.setEm(em);
}
// 空心
if(null != style.getOutline()){
BooleanDefaultTrue outline = new BooleanDefaultTrue();
outline.setVal(style.getOutline());
rpr.setOutline(outline);
}
// 设置上标下标
if(null != style.getVerticalAlign()){
CTVerticalAlignRun value = new CTVerticalAlignRun();
value.setVal(style.getVerticalAlign());
rpr.setVertAlign(value);
}
// 设置字符间距缩进
if(null != style.getIndent()){
CTTextScale value = new CTTextScale();
value.setVal(style.getIndent());
rpr.setW(value);
}
// 设置字符间距信息
if(null != style.getSpacing()){
CTSignedTwipsMeasure value = new CTSignedTwipsMeasure();
value.setVal(style.getSpacing());
rpr.setSpacing(value);
}
// 设置文本位置
if(null != style.getPosition()){
CTSignedHpsMeasure ctPosition = new CTSignedHpsMeasure();
ctPosition.setVal(style.getPosition());
rpr.setPosition(ctPosition);
}
// 阴文
if(null != style.getImprint()){
BooleanDefaultTrue imprint = new BooleanDefaultTrue();
imprint.setVal(style.getImprint());
rpr.setImprint(imprint);
}
// 阳文
if(null != style.getEmboss()){
BooleanDefaultTrue emboss = new BooleanDefaultTrue();
emboss.setVal(style.getEmboss());
rpr.setEmboss(emboss);
}
// 设置隐藏
if(null != style.getVanish()){
BooleanDefaultTrue vanish = new BooleanDefaultTrue();
vanish.setVal(style.getVanish());
rpr.setVanish(vanish);
}
// 设置阴影
if(null != style.getShadow()){
BooleanDefaultTrue shadow = new BooleanDefaultTrue();
shadow.setVal(style.getShadow());
rpr.setShadow(shadow);
}
// 设置底纹
if(null != style.getShading()){
CTShd shd = new CTShd();
shd.setVal(style.getShading());
rpr.setShd(shd);
}
// 设置突出显示文本
if(null != style.getHightlight()){
Highlight highlight = new Highlight();
highlight.setVal(style.getHightlight());
rpr.setHighlight(highlight);
}
// 设置删除线
if(null != style.getStrike()){
BooleanDefaultTrue strike = new BooleanDefaultTrue();
strike.setVal(style.getStrike());
rpr.setStrike(strike);
}
// 设置双删除线
if(null != style.getDoubleStrike()){
BooleanDefaultTrue strike = new BooleanDefaultTrue();
strike.setVal(style.getDoubleStrike());
rpr.setDstrike(strike);
}
// 倾斜
if(null != style.getTilt()){
BooleanDefaultTrue b = new BooleanDefaultTrue();
b.setVal(style.getTilt());
rpr.setI(b);
}
return rpr;
}
设置表格宽度
/**
* 设置表格宽度
* @param val 宽度 5000为百分之百的宽度
* @return TblWidth
*/
public static TblWidth buildTblWidth(BigInteger val){
TblWidth width = new TblWidth();
width.setW(val);
//此处试了几种方式均不好用,只有这个pct的合适,50分之一是一个百分点,5000为百分之百的宽度
width.setType("pct");
return width;
}
模板参数替换
/**
* 模板参数替换
* 格式 ${param1}
*/
public static void variableReplace(MainDocumentPart main, HashMap<String, String> params) throws JAXBException, Docx4JException{
main.variableReplace(params);
}
/**
* 模板参数替换
* 格式 ${param1}
*/
public static void variableReplace(WordprocessingMLPackage wordMLPackage, HashMap<String, String> params) throws JAXBException, Docx4JException{
// 提取正文
MainDocumentPart main = wordMLPackage.getMainDocumentPart();
variableReplace(main, params);
}
生成目录
/**
* 生成目录
* @param wordMLPackage WordprocessingMLPackage
* @param index 生成目录位置
* @param tocHeadingText 目录标题
*/
public static void tocGenerator(WordprocessingMLPackage wordMLPackage, int index, String tocHeadingText) throws TocException {
TocGenerator tocGenerator = new TocGenerator(wordMLPackage);
if(StringUtils.isNotBlank(tocHeadingText)){
Toc.setTocHeadingText(tocHeadingText);
}
// skipPageNumbering如果设置为TRUE 则会联网 要付费
tocGenerator.generateToc(index, "TOC \\o \"1-3\" \\h \\z \\u", true);
}
构造表格边框样式
/**
* 构造表格边框样式
* @param style 样式配置
* @return CTBorder
*/
public static CTBorder buildTableBorder(TableBorderStyle style){
CTBorder border = new CTBorder();
if(StringUtils.isNotBlank(style.getColor())){
border.setColor(style.getColor());
}
if(null != style.getSize()){
border.setSz(style.getSize());
}
if(null != style.getSpace()){
border.setSpace(style.getSpace());
}
STBorder val = null != style.getStyle() ? style.getStyle() : STBorder.SINGLE;
border.setVal(val);
return border;
}
设置表格边框样式
/**
* 设置表格边框样式
* @param top 上边框
* @param bottom 下边框
* @param left 左边框
* @param right 右边框
* @return TblBorders
*/
public static TblBorders setTableBorder(CTBorder top, CTBorder bottom, CTBorder left, CTBorder right){
TblBorders borders = new TblBorders();
borders.setBottom(top);
borders.setLeft(bottom);
borders.setRight(left);
borders.setTop(right);
// borders.setInsideH(border);
// borders.setInsideV(border);
return borders;
}
FontStyle
import lombok.Data;
import org.docx4j.wml.STEm;
import org.docx4j.wml.STShd;
import org.docx4j.wml.STVerticalAlignRun;
import org.docx4j.wml.UnderlineEnumeration;
import java.math.BigInteger;
/**
* 字体样式
*/
@Data
public class FontStyle {
/** 中文字体 tips:宋体 **/
private String cnFontFamily;
/** 英文字体 **/
private String enFontFamily;
/** 字体大小 **/
private BigInteger size;
/** 字体颜色 **/
private String color;
/** 是否加粗 **/
private Boolean bold;
/** 是否斜体 **/
private Boolean italic;
/** 是否删除线 **/
private Boolean deleteLine;
/**
* 设置下划线
* UnderlineEnumeration.SINGLE 单下划线
* UnderlineEnumeration.DOUBLE 双下划线
* UnderlineEnumeration.DASH 虚线
* UnderlineEnumeration.WAVE 波浪线
*/
private UnderlineEnumeration underlineEnumeration;
/** 背景颜色 **/
private STShd backgroundColor;
/** 字体边框颜色 **/
private String borderColor;
/** 字体边框大小 **/
private BigInteger borderSize;
/** 字体边框间距 **/
private BigInteger borderSpace;
/** 字体边框阴影 **/
private Boolean borderShadow;
/** 着重号 **/
private STEm emphasis;
/** 空心 **/
private Boolean outline;
/** 设置上标下标 **/
private STVerticalAlignRun verticalAlign;
/** 设置字符间距缩进 **/
private Integer indent;
/** 设置字符间距信息 **/
private BigInteger spacing;
/** 设置文本位置 **/
private BigInteger position;
/** 阴文 **/
private Boolean imprint;
/** 阳文 **/
private Boolean emboss;
/** 设置隐藏 **/
private Boolean vanish;
/** 设置阴影 **/
private Boolean shadow;
/** 设置底纹 **/
private STShd shading;
/** 设置突出显示文本 **/
private String hightlight;
/** 设置单删除线 **/
private Boolean strike;
/** 设置双删除线 **/
private Boolean doubleStrike;
/** 倾斜 **/
private Boolean tilt;
}
TableBorderStyle
import lombok.Data;
import org.docx4j.wml.STBorder;
import java.math.BigInteger;
/**
* 表格边框样式
*/
@Data
public class TableBorderStyle {
/** 边框大小 **/
private BigInteger size;
/** 边框间距 **/
private BigInteger space;
/** 边框颜色 **/
private String color;
/** 边框样式 **/
private STBorder style;
}
7.目录相关操作疑问
目前看 目录如果需要带页码就需要企业版, 还有生成和查找方法,目前找到的都不行,只有这样做法能勉强达到效果,但生成的目录点击跳转不了,求大神指导~~
TocGenerator tocGenerator = new TocGenerator(wordMLPackage);
if(StringUtils.isNotBlank(tocHeadingText)){
Toc.setTocHeadingText(tocHeadingText);
}
// skipPageNumbering如果设置为TRUE 则会联网 要付费
tocGenerator.generateToc(index, "TOC \\o \"1-3\" \\h \\z \\u", true);
其他方法如下:
public static void main(String[] args) throws Exception{
TocGenerator tocGenerator = new TocGenerator(wordMLPackage);
Toc.setTocHeadingText("目录");
tocGenerator.generateToc( 3, "TOC \\o \"1-3\"", true);
Document wmlDocumentEl = main.getJaxbElement();
Body body = wmlDocumentEl.getBody();
TocFinder finder = new TocFinder();
new TraversalUtil(body.getContent(), finder);
System.out.println(finder.getTocSDT().getSdtContent().getContent().size());
wordMLPackage.getMainDocumentPart()
.getDocumentSettingsPart().getJaxbElement()
.setUpdateFields(new BooleanDefaultTrue());
TocGenerator tocGenerator = new TocGenerator(wordMLPackage);
tocGenerator.updateToc( true);
VariablePrepare.prepare(wordMLPackage);
ObjectFactory factory = Context.getWmlObjectFactory();
P paragraph = factory.createP();
// addFieldBegin
addFieldBegin(factory, paragraph);
addTableOfCententField(factory, paragraph);
// addFieldEnd
addFieldEnd(factory, paragraph);
}
private static void addFieldBegin(ObjectFactory factory, P paragraph){
R run = factory.createR();
FldChar fldChar = factory.createFldChar();
fldChar.setFldCharType(STFldCharType.BEGIN);
fldChar.setDirty(true);
run.getContent().add(getWrappendFldChar(fldChar));
paragraph.getContent().add(run);
}
private static void addTableOfCententField(ObjectFactory factory, P paragraph){
R run = factory.createR();
Text text = new Text();
text.setSpace("preserve");
text.setValue("TOC \\o \"1-3\" \\h \\z \\u");
run.getContent().add(factory.createRInstrText(text));
paragraph.getContent().add(run);
}
private static void addFieldEnd(ObjectFactory factory, P paragraph){
R run = factory.createR();
FldChar fldChar = factory.createFldChar();
fldChar.setFldCharType(STFldCharType.END);
fldChar.setDirty(true);
run.getContent().add(getWrappendFldChar(fldChar));
paragraph.getContent().add(run);
}
private static JAXBElement getWrappendFldChar(FldChar fldChar){
return new JAXBElement(new QName(Namespaces.NS_WORD12, "fldChar"), FldChar.class, fldChar);
}