PoiService.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. package cn.cslg.pas.service;
  2. import cn.cslg.pas.common.model.vo.PoiVO;
  3. import cn.cslg.pas.domain.PatentPledge;
  4. import cn.cslg.pas.mapper.PatentPledgeMapper;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import lombok.RequiredArgsConstructor;
  7. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  8. import org.apache.poi.util.LocaleUtil;
  9. import org.apache.poi.util.Units;
  10. import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
  11. import org.apache.poi.xwpf.usermodel.*;
  12. import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
  13. import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
  14. import org.springframework.context.annotation.Lazy;
  15. import org.springframework.stereotype.Service;
  16. import java.io.FileInputStream;
  17. import java.io.FileOutputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.math.BigInteger;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. /**
  24. * <p>
  25. * 专利信息质押质权人表 服务类
  26. * </p>
  27. *
  28. * @author 王岩
  29. * @since 2022-02-24
  30. */
  31. @Service
  32. @RequiredArgsConstructor(onConstructor_ = {@Lazy})
  33. public class PoiService extends ServiceImpl<PatentPledgeMapper, PatentPledge> {
  34. public PoiVO readWordFile() throws IOException {
  35. PoiVO poiVO = new PoiVO();
  36. List<PoiVO.Pg> pgs = new ArrayList<>();
  37. InputStream is = new FileInputStream("C:\\\\BaiduNetdiskDownload\\\\生成\\\\first.docx");
  38. XWPFDocument doc = new XWPFDocument(is);
  39. List<IBodyElement> bodyElements = doc.getBodyElements();
  40. for (IBodyElement iBodyElement : bodyElements) {
  41. PoiVO.Pg pg = new PoiVO.Pg();
  42. if (iBodyElement.getElementType().name().equals("PARAGRAPH")) {
  43. XWPFParagraph paragraph = (XWPFParagraph) iBodyElement;
  44. if (paragraph.getStyle() != null && paragraph.getStyle().equals("word")) {
  45. XWPFRun rh = paragraph.getRuns().get(0);
  46. pg.setFontSize(rh.getFontSize());
  47. pg.setFontFamily(rh.getFontFamily());
  48. pg.setText(rh.getText(0));
  49. pg.setColor(rh.getColor());
  50. pg.setAlignment(paragraph.getFontAlignment());
  51. pg.setType(paragraph.getStyle());
  52. pgs.add(pg);
  53. } else if (paragraph.getStyle() != null && paragraph.getStyle().equals("picture")) {
  54. XWPFRun rh = paragraph.getRuns().get(0);
  55. pg.setAlignment(paragraph.getFontAlignment());
  56. pg.setType(paragraph.getStyle());
  57. XWPFPicture picture = rh.getEmbeddedPictures().get(0);
  58. pg.setHeight((int) picture.getDepth());
  59. pg.setWeight((int) picture.getWidth());
  60. pg.setImgUrl(picture.getDescription());
  61. pgs.add(pg);
  62. } else if (paragraph.getStyle() != null && paragraph.getStyle().contains("Heading")) {
  63. XWPFRun rh = paragraph.getRuns().get(0);
  64. pg.setFontSize(rh.getFontSize());
  65. pg.setFontFamily(rh.getFontFamily());
  66. pg.setText(rh.getText(0));
  67. pg.setColor(rh.getColor());
  68. pg.setAlignment(paragraph.getFontAlignment());
  69. pg.setType(paragraph.getStyle());
  70. pgs.add(pg);
  71. }
  72. } else if (iBodyElement.getElementType().name().equals("TABLE")) {
  73. XWPFTable table = (XWPFTable) iBodyElement;
  74. String org = table.getText().replace("\t", ",").replace("\n", "||");
  75. String tableText = org.replace(",||", "");
  76. pg.setText(tableText);
  77. pg.setType(table.getStyleID());
  78. pgs.add(pg);
  79. }
  80. }
  81. List<XWPFParagraph> ps = doc.getParagraphs();
  82. PoiVO.Pg title = new PoiVO.Pg();
  83. title.setAlignment(ps.get(0).getFontAlignment());
  84. XWPFRun r = ps.get(0).getRuns().get(0);
  85. title.setColor(r.getColor());
  86. title.setText(r.getText(0));
  87. title.setFontSize(r.getFontSize());
  88. poiVO.setPgs(pgs);
  89. poiVO.setTitle(title);
  90. return poiVO;
  91. }
  92. public void writeFile(PoiVO poiVO) throws IOException, InvalidFormatException {
  93. XWPFDocument doc = new XWPFDocument();// 创建Word文件
  94. PoiVO.Pg title = poiVO.getTitle();
  95. // 标题
  96. XWPFParagraph p = doc.createParagraph();// 新建段落
  97. p.setFontAlignment(title.getAlignment());// 设置段落的对齐方式
  98. XWPFRun r = p.createRun();//创建标题
  99. r.setText(title.getText());
  100. r.setBold(title.getBold());//设置为粗体
  101. r.setColor(title.getColor());//设置颜色
  102. r.setFontSize(title.getFontSize());//设置字体大小
  103. r.setStyle("Title");
  104. if (title.getAddCarriageReturn()) {
  105. r.addCarriageReturn();//回车换行
  106. }
  107. doc.createParagraph().createRun().addBreak(BreakType.PAGE);//换页
  108. List<PoiVO.Pg> pgs = poiVO.getPgs();
  109. CTSdtBlock ctSdtBlock = doc.getDocument().getBody().addNewSdt();
  110. this.CustomTOC(ctSdtBlock);
  111. doc.createParagraph().createRun().addBreak(BreakType.PAGE);//换页
  112. for (int i = 0; i < pgs.size(); i++) {
  113. if (pgs.get(i).getType() != null && pgs.get(i).getType().equals("word")) {
  114. XWPFParagraph tm = doc.createParagraph();
  115. tm.setStyle("word");
  116. XWPFRun rh = tm.createRun();
  117. rh.setFontSize(pgs.get(i).getFontSize());
  118. rh.setFontFamily(pgs.get(i).getFontFamily());
  119. rh.setText(pgs.get(i).getText());
  120. rh.setColor(pgs.get(i).getColor());
  121. tm.setFontAlignment(pgs.get(i).getAlignment());
  122. rh.setFontFamily(pgs.get(i).getFontFamily());
  123. if (pgs.get(i).getAddCarriageReturn()) {
  124. rh.addCarriageReturn();//回车换行
  125. }
  126. } else if (pgs.get(i).getType() != null && pgs.get(i).getType().equals("picture")) {
  127. XWPFParagraph pImg = doc.createParagraph();
  128. pImg.setStyle("picture");
  129. pImg.setFontAlignment(pgs.get(i).getAlignment());
  130. XWPFRun rImg = pImg.createRun();//创建标题
  131. rImg.addCarriageReturn();//回车换行
  132. String imgData = pgs.get(i).getImgUrl();
  133. // 转为数据流
  134. InputStream stream = new FileInputStream(imgData);
  135. // 向段落中插入图片
  136. rImg.addPicture(stream, Document.PICTURE_TYPE_PNG, pgs.get(i).getImgUrl(), Units.toEMU(pgs.get(i).getWeight()), Units.toEMU(pgs.get(i).getHeight()));
  137. } else if (pgs.get(i).getType() != null && pgs.get(i).getType().equals("table")) {
  138. String org = pgs.get(i).getText();
  139. int rows;
  140. int cols = 0;
  141. String[] row = org.split("\\|\\|");
  142. rows = row.length;
  143. for (String s : row) {
  144. String[] tem = s.split(",");
  145. cols = Math.max(cols, tem.length);
  146. }
  147. XWPFTable table1 = doc.createTable(rows, cols);
  148. table1.setStyleID(pgs.get(i).getType());
  149. table1.setWidthType(TableWidthType.AUTO);
  150. for (int t = 0; t < row.length; t++) {
  151. String[] tem = row[t].split(",");
  152. XWPFTableRow row1 = table1.getRow(t);
  153. for (int q = 0; q < tem.length; q++) {
  154. row1.getCell(q).setText(tem[q]);
  155. }
  156. }
  157. doc.setTable(0, table1);
  158. } else if (pgs.get(i).getType().contains("Heading")) {
  159. XWPFParagraph Paragraph = doc.createParagraph();
  160. CTBookmark ctBookmark1 = Paragraph.getCTP().addNewBookmarkStart();//开始书签
  161. ctBookmark1.setId(BigInteger.valueOf(i));//开始书签和结束书签通过ID关联
  162. ctBookmark1.setName("书签" + i);//书签名称
  163. Paragraph.setStyle(pgs.get(i).getType());
  164. XWPFRun run1 = Paragraph.createRun();
  165. run1.setText(pgs.get(i).getText());
  166. run1.setColor(pgs.get(i).getColor());
  167. run1.setFontSize(pgs.get(i).getFontSize());
  168. run1.setBold(true);
  169. Paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(i));
  170. }
  171. }
  172. this.addItem2TOC(doc, ctSdtBlock);
  173. Integer pageCount = doc.getProperties().getExtendedProperties().getUnderlyingProperties().getPages();
  174. FileOutputStream out = new FileOutputStream("C:\\\\BaiduNetdiskDownload\\\\生成\\\\first.docx");
  175. CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
  176. XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(doc, sectPr);
  177. // this.createDefaultFooter(doc,"宋体",8);
  178. // 添加页脚,
  179. CTP ctpFooter = CTP.Factory.newInstance();
  180. CTR ctrFooter = ctpFooter.addNewR();
  181. CTText ctFooter = ctrFooter.addNewT();
  182. String footerText = "ctpFooter";
  183. ctFooter.setStringValue(footerText);
  184. XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, doc);
  185. XWPFParagraph[] parsFooter = new XWPFParagraph[1];
  186. parsFooter[0] = footerParagraph;
  187. policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);
  188. doc.write(out);
  189. out.close();
  190. System.out.println("Process Completed Successfully");
  191. }
  192. public void addItem2TOC(XWPFDocument doc, CTSdtBlock block) {
  193. List<XWPFParagraph> paragraphs = doc.getParagraphs();
  194. int num = 1;
  195. for (XWPFParagraph par : paragraphs) {
  196. String parStyle = par.getStyle();
  197. List<CTR> ctrlist = par.getCTP().getRList();//获取<w:p>标签下的<w:r>list
  198. for (CTR r : ctrlist) { //遍历r
  199. List<CTEmpty> breaklist = r.getLastRenderedPageBreakList();//判断是否存在此标签
  200. if (breaklist.size() > 0) {
  201. num++; //页数添加
  202. }
  203. }
  204. if (parStyle != null && parStyle.startsWith("Heading")) {
  205. List<CTBookmark> bookmarkList = par.getCTP().getBookmarkStartList();
  206. try {
  207. int level = Integer.parseInt(parStyle.substring("Heading".length()));
  208. //添加标题
  209. this.addRow(level, par.getText(), num, bookmarkList.get(0).getName(), block);
  210. } catch (NumberFormatException e) {
  211. e.printStackTrace();
  212. }
  213. }
  214. }
  215. }
  216. //生成页脚
  217. public static void createDefaultFooter(final XWPFDocument document, String fontName, int fontSize) throws IOException {
  218. CTP pageNo = CTP.Factory.newInstance();
  219. XWPFParagraph footer = new XWPFParagraph(pageNo, document);
  220. footer.createRun().setFontSize(2000);
  221. CTPPr begin = pageNo.addNewPPr();
  222. begin.addNewPStyle().setVal("style21");
  223. begin.addNewJc().setVal(STJc.CENTER);
  224. CTR pageBegin = pageNo.addNewR();
  225. pageBegin.addNewRPr().addNewRFonts().setAscii(fontName);
  226. pageBegin.addNewRPr().addNewRFonts().setCs(fontName);
  227. pageBegin.addNewRPr().addNewRFonts().setEastAsia(fontName);
  228. pageBegin.addNewRPr().addNewRFonts().setHAnsi(fontName);
  229. pageBegin.addNewRPr().addNewSz().setVal(BigInteger.valueOf(fontSize));
  230. pageBegin.addNewRPr().addNewSzCs().setVal(BigInteger.valueOf(fontSize));
  231. pageBegin.addNewFldChar().setFldCharType(STFldCharType.BEGIN);
  232. CTR page = pageNo.addNewR();
  233. page.addNewRPr().addNewRFonts().setAscii(fontName);
  234. page.addNewRPr().addNewRFonts().setCs(fontName);
  235. page.addNewRPr().addNewRFonts().setEastAsia(fontName);
  236. page.addNewRPr().addNewRFonts().setHAnsi(fontName);
  237. page.addNewRPr().addNewSz().setVal(BigInteger.valueOf(fontSize));
  238. page.addNewRPr().addNewSzCs().setVal(BigInteger.valueOf(fontSize));
  239. page.addNewInstrText().setStringValue("PAGE \\* MERGEFORMAT");
  240. CTR pageSep = pageNo.addNewR();
  241. pageSep.addNewRPr().addNewRFonts().setAscii(fontName);
  242. pageSep.addNewRPr().addNewRFonts().setCs(fontName);
  243. pageSep.addNewRPr().addNewRFonts().setEastAsia(fontName);
  244. pageSep.addNewRPr().addNewRFonts().setHAnsi(fontName);
  245. pageSep.addNewRPr().addNewSz().setVal(BigInteger.valueOf(fontSize));
  246. pageSep.addNewRPr().addNewSzCs().setVal(BigInteger.valueOf(fontSize));
  247. pageSep.addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
  248. CTR end = pageNo.addNewR();
  249. CTRPr endRPr = end.addNewRPr();
  250. endRPr.addNewNoProof();
  251. endRPr.addNewLang().setVal("zh-CN");
  252. end.addNewRPr().addNewRFonts().setAscii(fontName);
  253. end.addNewRPr().addNewRFonts().setCs(fontName);
  254. end.addNewRPr().addNewRFonts().setEastAsia(fontName);
  255. end.addNewRPr().addNewRFonts().setHAnsi(fontName);
  256. end.addNewRPr().addNewSz().setVal(BigInteger.valueOf(fontSize));
  257. end.addNewRPr().addNewSzCs().setVal(BigInteger.valueOf(fontSize));
  258. end.addNewFldChar().setFldCharType(STFldCharType.END);
  259. CTSectPr sectPr = document.getDocument().getBody().isSetSectPr() ? document.getDocument().getBody().getSectPr() : document.getDocument().getBody().addNewSectPr();
  260. XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);
  261. policy.createFooter(STHdrFtr.DEFAULT, new XWPFParagraph[]{footer});
  262. }
  263. // 目录添加行
  264. public void addRow(int level, String title, int page, String bookmarkRef, CTSdtBlock block) {
  265. CTSdtContentBlock contentBlock = block.getSdtContent();
  266. CTP p = contentBlock.addNewP();
  267. p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
  268. p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
  269. CTPPr pPr = p.addNewPPr();
  270. pPr.addNewPStyle().setVal("TOC" + level);
  271. CTTabs tabs = pPr.addNewTabs();//Set of Custom Tab Stops自定义制表符集合
  272. CTTabStop tab = tabs.addNewTab();//Custom Tab Stop自定义制表符
  273. tab.setVal(STTabJc.RIGHT);
  274. tab.setLeader(STTabTlc.DOT);
  275. tab.setPos(new BigInteger("9100"));//默认为8290,因为调整过页边距,所有需要调整,手动设置找出最佳值
  276. pPr.addNewRPr().addNewNoProof();//不检查语法
  277. CTR run = p.addNewR();
  278. run.addNewRPr().addNewNoProof();
  279. for (int i = 0; i < level; i++) {
  280. title = "\n" + title;
  281. }
  282. run.addNewT().setStringValue(title);//添加标题文字
  283. //设置标题字体
  284. CTRPr pRpr = run.getRPr();
  285. CTFonts fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr.addNewRFonts();
  286. fonts.setAscii("Times New Roman");
  287. fonts.setEastAsia("楷体");
  288. fonts.setHAnsi("楷体");
  289. // 设置标题字体大小
  290. CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
  291. sz.setVal(new BigInteger("21"));
  292. CTHpsMeasure szCs = pRpr.isSetSzCs() ? pRpr.getSzCs() : pRpr.addNewSzCs();
  293. szCs.setVal(new BigInteger("21"));
  294. //添加制表符
  295. run = p.addNewR();
  296. run.addNewRPr().addNewNoProof();
  297. run.addNewTab();
  298. //添加页码左括号
  299. p.addNewR().addNewT().setStringValue("(");
  300. //STFldCharType.BEGIN标识与结尾处STFldCharType.END相对应
  301. run = p.addNewR();
  302. run.addNewRPr().addNewNoProof();
  303. run.addNewFldChar().setFldCharType(STFldCharType.BEGIN);//Field Character Type
  304. // pageref run
  305. run = p.addNewR();
  306. run.addNewRPr().addNewNoProof();
  307. CTText text = run.addNewInstrText();//Field Code 添加域代码文本控件
  308. text.setSpace(SpaceAttribute.Space.PRESERVE);
  309. // bookmark reference
  310. //源码的域名为" PAGEREF _Toc","\h"含义为在目录内建立目录项与页码的超链接
  311. text.setStringValue(" PAGEREF " + bookmarkRef + " \\h ");
  312. p.addNewR().addNewRPr().addNewNoProof();
  313. run = p.addNewR();
  314. run.addNewRPr().addNewNoProof();
  315. run.addNewFldChar().setFldCharType(STFldCharType.SEPARATE);
  316. // page number run
  317. run = p.addNewR();
  318. run.addNewRPr().addNewNoProof();
  319. run.addNewT().setStringValue(Integer.toString(page));
  320. run = p.addNewR();
  321. run.addNewRPr().addNewNoProof();
  322. //STFldCharType.END标识与上面STFldCharType.BEGIN相对应
  323. run.addNewFldChar().setFldCharType(STFldCharType.END);
  324. //添加页码右括号
  325. p.addNewR().addNewT().setStringValue(")");
  326. //设置行间距
  327. CTSpacing pSpacing = pPr.getSpacing() != null ? pPr.getSpacing() : pPr.addNewSpacing();
  328. pSpacing.setLineRule(STLineSpacingRule.AUTO);//行间距类型:多倍
  329. pSpacing.setLine(new BigInteger("360"));//此处1.5倍行间距
  330. }
  331. //添加目录
  332. public void CustomTOC(CTSdtBlock block) {
  333. CTSdtPr sdtPr = block.addNewSdtPr();
  334. CTDecimalNumber id = sdtPr.addNewId();
  335. id.setVal(new BigInteger("4844945"));
  336. sdtPr.addNewDocPartObj().addNewDocPartGallery().setVal("Table of contents");
  337. CTSdtEndPr sdtEndPr = block.addNewSdtEndPr();
  338. CTRPr rPr = sdtEndPr.addNewRPr();
  339. CTFonts fonts = rPr.addNewRFonts();
  340. fonts.setAsciiTheme(STTheme.MINOR_H_ANSI);
  341. fonts.setEastAsiaTheme(STTheme.MINOR_H_ANSI);
  342. fonts.setHAnsiTheme(STTheme.MINOR_H_ANSI);
  343. fonts.setCstheme(STTheme.MINOR_BIDI);
  344. rPr.addNewB().setVal(STOnOff.OFF);
  345. rPr.addNewBCs().setVal(STOnOff.OFF);
  346. rPr.addNewColor().setVal("auto");
  347. rPr.addNewSz().setVal(new BigInteger("24"));
  348. rPr.addNewSzCs().setVal(new BigInteger("24"));
  349. CTSdtContentBlock content = block.addNewSdtContent();
  350. CTP p = content.addNewP();
  351. p.setRsidR("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
  352. p.setRsidRDefault("00EF7E24".getBytes(LocaleUtil.CHARSET_1252));
  353. p.addNewPPr().addNewPStyle().setVal("TOCHeading");
  354. p.addNewR().addNewT().setStringValue("目 录");//源码中为"Table of contents"
  355. //设置段落对齐方式,即将“目录”二字居中
  356. CTPPr pr = p.getPPr();
  357. CTJc jc = pr.isSetJc() ? pr.getJc() : pr.addNewJc();
  358. STJc.Enum en = STJc.Enum.forInt(ParagraphAlignment.CENTER.getValue());
  359. jc.setVal(en);
  360. //"目录"二字的字体
  361. CTRPr pRpr = p.getRArray(0).addNewRPr();
  362. fonts = pRpr.isSetRFonts() ? pRpr.getRFonts() : pRpr.addNewRFonts();
  363. fonts.setAscii("Times New Roman");
  364. fonts.setEastAsia("华文中宋");
  365. fonts.setHAnsi("华文中宋");
  366. //"目录"二字加粗
  367. CTOnOff bold = pRpr.isSetB() ? pRpr.getB() : pRpr.addNewB();
  368. bold.setVal(STOnOff.TRUE);
  369. // 设置“目录”二字字体大小为24号
  370. CTHpsMeasure sz = pRpr.isSetSz() ? pRpr.getSz() : pRpr.addNewSz();
  371. sz.setVal(new BigInteger("36"));
  372. }
  373. }