com.github.xiao1wang.wordapp.renderData.TOCRenderData Maven / Gradle / Ivy
package com.github.xiao1wang.wordapp.renderData;
import com.deepoove.poi.data.RenderData;
import com.deepoove.poi.xwpf.BodyContainer;
import com.deepoove.poi.xwpf.BodyContainerFactory;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtBlock;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentBlock;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtEndPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabStop;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTabs;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTabTlc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTheme;
import java.math.BigInteger;
import java.util.List;
/**
* TODO: 目录数据
*/
public class TOCRenderData implements RenderData {
// 目录下的标题基本到几层结构
private int maxLevel = 0;
// 目录标题
private String title = null;
// 域所在的位置块
private CTSdtBlock block;
// 当前操作的文档
private NiceXWPFDocument document = null;
// 当前操作的位置
private XWPFRun run = null;
public TOCRenderData(String title, int maxLevel) {
this.title = title;
this.maxLevel = maxLevel;
}
public TOCRenderData(int maxLevel, String title) {
this.maxLevel = maxLevel;
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public CTSdtBlock getBlock() {
return block;
}
public void setBlock(CTSdtBlock block) {
this.block = block;
}
public int getMaxLevel() {
return maxLevel;
}
public void setMaxLevel(int maxLevel) {
this.maxLevel = maxLevel;
}
public NiceXWPFDocument getDocument() {
return document;
}
public void setDocument(NiceXWPFDocument document) {
this.document = document;
}
public XWPFRun getRun() {
return run;
}
public void setRun(XWPFRun run) {
this.run = run;
}
/**
* 设置目录的标题
*/
public void setTOCTitle() {
CTSdtPr sdtPr = block.addNewSdtPr();
CTDecimalNumber id = sdtPr.addNewId();
id.setVal(new BigInteger("4844945"));
sdtPr.addNewDocPartObj().addNewDocPartGallery().setVal("Table of contents");
CTSdtEndPr sdtEndPr = block.addNewSdtEndPr();
CTRPr rPr = sdtEndPr.addNewRPr();
CTFonts fonts = rPr.addNewRFonts();
fonts.setAsciiTheme(STTheme.MINOR_H_ANSI);
fonts.setEastAsiaTheme(STTheme.MINOR_H_ANSI);
fonts.setHAnsiTheme(STTheme.MINOR_H_ANSI);
fonts.setCstheme(STTheme.MINOR_BIDI);
rPr.addNewB().setVal(STOnOff.OFF);
rPr.addNewBCs().setVal(STOnOff.OFF);
rPr.addNewColor().setVal("auto");
rPr.addNewSz().setVal(new BigInteger("24"));
rPr.addNewSzCs().setVal(new BigInteger("24"));
CTSdtContentBlock content = block.addNewSdtContent();
CTP p = content.addNewP();
p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
p.addNewPPr().addNewPStyle().setVal("TOCHeading");
p.addNewR().addNewT().setStringValue(title);
//设置段落对齐方式,即将“目录”二字居中
CTPPr pr = p.getPPr();
CTJc jc = pr.isSetJc() ? pr.getJc() : pr.addNewJc();
STJc.Enum en = STJc.Enum.forInt(ParagraphAlignment.CENTER.getValue());
jc.setVal(en);
//"目录"二字的字体
CTRPr pRpr = p.getRArray(0).addNewRPr();
fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr.addNewRFonts();
fonts.setAscii("Times New Roman");
fonts.setEastAsia("华文中宋");
fonts.setHAnsi("华文中宋");
//"目录"二字加粗
CTOnOff bold = pRpr.isSetB() ? pRpr.getB() : pRpr.addNewB();
bold.setVal(STOnOff.TRUE);
// 设置“目录”二字字体大小为24号
CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
sz.setVal(new BigInteger("36"));
}
/**
* 设置目录的标题
*/
public void setTOCTitleFirst() {
BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run);
XWPFParagraph paragraph = bodyContainer.insertNewParagraph(run);
CTP p = paragraph.getCTP();
p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
p.addNewPPr().addNewPStyle().setVal("TOCHeading");
p.addNewR().addNewT().setStringValue(title);
//设置段落对齐方式,即将“目录”二字居中
CTPPr pr = p.getPPr();
CTJc jc = pr.isSetJc() ? pr.getJc() : pr.addNewJc();
STJc.Enum en = STJc.Enum.forInt(ParagraphAlignment.CENTER.getValue());
jc.setVal(en);
//"目录"二字的字体
CTRPr pRpr = p.getRArray(0).addNewRPr();
//"目录"二字加粗
CTOnOff bold = pRpr.isSetB() ? pRpr.getB() : pRpr.addNewB();
bold.setVal(STOnOff.TRUE);
// 设置“目录”二字字体大小为24号
CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
sz.setVal(new BigInteger("36"));
}
public void setItem2TOC(NiceXWPFDocument doc) {
BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run);
List bodyElementList = doc.getBodyElements();
if(bodyElementList != null && bodyElementList.size() >0) {
int index = 0;
for (IBodyElement element : bodyElementList) {
if(element instanceof XWPFParagraph) {
XWPFParagraph par = (XWPFParagraph) element;
String parStyle = par.getStyle();
if (parStyle != null && StringUtils.isNumeric(parStyle)) {
List bookmarkList=par.getCTP().getBookmarkStartList();
try {
int level = Integer.parseInt(parStyle);
if(level <= maxLevel) {
String title = par.getText();
String bookmarkRef = null;
if(bookmarkList == null || bookmarkList.size() == 0) {
bookmarkRef = "_Toc112723803" + (index++);
} else {
bookmarkRef = bookmarkList.get(bookmarkList.size()-1).getName();
}
XWPFParagraph paragraph = bodyContainer.insertNewParagraph(run);
CTP p = paragraph.getCTP();
p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
CTPPr pPr = p.addNewPPr();
pPr.addNewPStyle().setVal((level*10)+"");
CTTabs tabs = pPr.addNewTabs();
CTTabStop tab = tabs.addNewTab();
tab.setVal(STTabJc.RIGHT);
tab.setLeader(STTabTlc.DOT);
tab.setPos(new BigInteger("8290"));
pPr.addNewRPr().addNewNoProof();
CTR run = p.addNewR();
run.addNewRPr().addNewNoProof();
run.addNewT().setStringValue(title);
run = p.addNewR();
run.addNewRPr().addNewNoProof();
run.addNewTab();
run = p.addNewR();
run.addNewRPr().addNewNoProof();
run.addNewFldChar().setFldCharType(STFldCharType.BEGIN);
run = p.addNewR();
run.addNewRPr().addNewNoProof();
CTText text = run.addNewInstrText();
text.setSpace(SpaceAttribute.Space.PRESERVE);
text.setStringValue(" PAGEREF " + bookmarkRef + " \\h ");
p.addNewR().addNewRPr().addNewNoProof();
run = p.addNewR();
run.addNewRPr().addNewNoProof();
run.addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
run = p.addNewR();
run.addNewRPr().addNewNoProof();
// 获取当前标题名称,是在文档的第几页出现的
int page = pageIndex(par, title, bodyElementList);
run.addNewT().setStringValue(Integer.toString(page));
run = p.addNewR();
run.addNewRPr().addNewNoProof();
run.addNewFldChar().setFldCharType(STFldCharType.END);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
}
}
}
public int pageIndex(XWPFParagraph currentPar, String headTitle, List bodyElementList) {
int page = 1;
boolean findFlag = false;
if(bodyElementList != null && bodyElementList.size() >0) {
for (int i=0; i ctrlist = par.getCTP().getRList();//获取标签下的list
for(int j=0; j < ctrlist.size(); j++) { //遍历r
CTR r = ctrlist.get(j);
List breaklist = r.getLastRenderedPageBreakList();//判断是否存在此标签
if(breaklist.size() > 0) {
page++; //页数添加
}
if(headTitle.equals(title) && currentPar == par) {
findFlag = true;
break;
}
}
} else if(element instanceof XWPFTable) {
XWPFTable table = (XWPFTable) element;
List tableList = table.getRows();
if(tableList != null && tableList.size() > 0) {
for(XWPFTableRow row : tableList) {
List cellList = row.getTableCells();
if(cellList != null && cellList.size() > 0) {
for(XWPFTableCell cell : cellList) {
List paragraphList = cell.getParagraphs();
if(paragraphList != null && paragraphList.size() > 0) {
for(XWPFParagraph par : paragraphList) {
List ctrlist = par.getCTP().getRList();//获取标签下的list
for(int j=0; j < ctrlist.size(); j++) { //遍历r
CTR r = ctrlist.get(j);
List breaklist = r.getLastRenderedPageBreakList();//判断是否存在此标签
if(breaklist.size() > 0) {
page++; //页数添加
}
}
}
}
}
}
}
}
}
}
}
if(!findFlag) {
page = 1;
}
return page;
}
}