.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); border-top-left-radius: 7px; border-top-right-radius: 7px; color: rgba(255, 255, 255, 1); height: 1.8em; line-height: 1.8em; padding: 5px }

转载请注明出处:https://www.cnblogs.com/sun-flower1314/p/10128796.html

本篇是关于利用Apache 的POI导出Word的实现步骤。采用XWPFDocument导出Word,结构和样式完全由代码控制,操作起来还是非常的不太方便,只能够创建简单的word,不能设置样式,功能太少。但在这里还是实现一下,毕竟做过。

关于导出Word的方案另一种方式:https://www.cnblogs.com/sun-flower1314/p/10126111.html 

首先声明一些基本概念:

XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档
XWPFParagraph代表文档、表格、标题等种的段落,由多个XWPFRun组成
XWPFRun代表具有同样风格的一段文本
XWPFTable代表一个表格
XWPFTableRow代表表格的一行
XWPFTableCell代表表格的一个单元格
XWPFChar 表示.docx文件中的图表
XWPFHyperlink 表示超链接
XWPFPicture 代表图片

注意:直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun。

先看效果图:(完全是由代码导出)

1.导入jar包:

(虽然只有两个,但是会自动依赖其他jar包进来)

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi-ooxml</artifactId>
  4. <version>3.17</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi</artifactId>
  9. <version>3.17</version>
  10. </dependency>

  这是依赖包:

     

2. 代码部分:

  1. package cn.hxc.myWorld.myWorld;
  2.  
  3. import java.io.IOException;
  4. import java.util.List;
  5. import java.util.Map;
  6.  
  7. import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
  8. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  9. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  10. import org.apache.poi.xwpf.usermodel.XWPFRun;
  11. import org.apache.poi.xwpf.usermodel.XWPFTable;
  12. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  13. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  14. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
  15. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
  16.  
  17. import cn.hxc.myWorld.util.XWPFHelper;
  18. import cn.hxc.myWorld.util.XWPFHelperTable;
  19.  
  20. /**
  21. * @Description 导出word文档
  22. * @Author Huangxiaocong
  23. * 2018年12月1日 下午12:12:15
  24. */
  25. public class ExportWord {
  26. private XWPFHelperTable xwpfHelperTable = null;
  27. private XWPFHelper xwpfHelper = null;
  28. public ExportWord() {
  29. xwpfHelperTable = new XWPFHelperTable();
  30. xwpfHelper = new XWPFHelper();
  31. }
  32. /**
  33. * 创建好文档的基本 标题,表格 段落等部分
  34. * @return
  35. * @Author Huangxiaocong 2018年12月16日
  36. */
  37. public XWPFDocument createXWPFDocument() {
  38. XWPFDocument doc = new XWPFDocument();
  39. createTitleParagraph(doc);
  40. createTableParagraph(doc, 10, 6);
  41. return doc;
  42. }
  43. /**
  44. * 创建表格的标题样式
  45. * @param document
  46. * @Author Huangxiaocong 2018年12月16日 下午5:28:38
  47. */
  48. public void createTitleParagraph(XWPFDocument document) {
  49. XWPFParagraph titleParagraph = document.createParagraph(); //新建一个标题段落对象(就是一段文字)
  50. titleParagraph.setAlignment(ParagraphAlignment.CENTER);//样式居中
  51. XWPFRun titleFun = titleParagraph.createRun(); //创建文本对象
  52. // titleFun.setText(titleName); //设置标题的名字
  53. titleFun.setBold(true); //加粗
  54. titleFun.setColor("000000");//设置颜色
  55. titleFun.setFontSize(25); //字体大小
  56. // titleFun.setFontFamily("");//设置字体
  57. //...
  58. titleFun.addBreak(); //换行
  59. }
  60. /**
  61. * 设置表格
  62. * @param document
  63. * @param rows
  64. * @param cols
  65. * @Author Huangxiaocong 2018年12月16日
  66. */
  67. public void createTableParagraph(XWPFDocument document, int rows, int cols) {
  68. // xwpfHelperTable.createTable(xdoc, rowSize, cellSize, isSetColWidth, colWidths)
  69. XWPFTable infoTable = document.createTable(rows, cols);
  70. xwpfHelperTable.setTableWidthAndHAlign(infoTable, "9072", STJc.CENTER);
  71. //合并表格
  72. xwpfHelperTable.mergeCellsHorizontal(infoTable, 1, 1, 5);
  73. xwpfHelperTable.mergeCellsVertically(infoTable, 0, 3, 6);
  74. for(int col = 3; col < 7; col++) {
  75. xwpfHelperTable.mergeCellsHorizontal(infoTable, col, 1, 5);
  76. }
  77. //设置表格样式
  78. List<XWPFTableRow> rowList = infoTable.getRows();
  79. for(int i = 0; i < rowList.size(); i++) {
  80. XWPFTableRow infoTableRow = rowList.get(i);
  81. List<XWPFTableCell> cellList = infoTableRow.getTableCells();
  82. for(int j = 0; j < cellList.size(); j++) {
  83. XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0);
  84. cellParagraph.setAlignment(ParagraphAlignment.CENTER);
  85. XWPFRun cellParagraphRun = cellParagraph.createRun();
  86. cellParagraphRun.setFontSize(12);
  87. if(i % 2 != 0) {
  88. cellParagraphRun.setBold(true);
  89. }
  90. }
  91. }
  92. xwpfHelperTable.setTableHeight(infoTable, 560, STVerticalJc.CENTER);
  93. }
  94.  
  95. /**
  96. * 往表格中填充数据
  97. * @param dataList
  98. * @param document
  99. * @throws IOException
  100. * @Author Huangxiaocong 2018年12月16日
  101. */
  102. @SuppressWarnings("unchecked")
  103. public void exportCheckWord(Map<String, Object> dataList, XWPFDocument document, String savePath) throws IOException {
  104. XWPFParagraph paragraph = document.getParagraphArray(0);
  105. XWPFRun titleFun = paragraph.getRuns().get(0);
  106. titleFun.setText(String.valueOf(dataList.get("TITLE")));
  107. List<List<Object>> tableData = (List<List<Object>>) dataList.get("TABLEDATA");
  108. XWPFTable table = document.getTableArray(0);
  109. fillTableData(table, tableData);
  110. xwpfHelper.saveDocument(document, savePath);
  111. }
  112. /**
  113. * 往表格中填充数据
  114. * @param table
  115. * @param tableData
  116. * @Author Huangxiaocong 2018年12月16日
  117. */
  118. public void fillTableData(XWPFTable table, List<List<Object>> tableData) {
  119. List<XWPFTableRow> rowList = table.getRows();
  120. for(int i = 0; i < tableData.size(); i++) {
  121. List<Object> list = tableData.get(i);
  122. List<XWPFTableCell> cellList = rowList.get(i).getTableCells();
  123. for(int j = 0; j < list.size(); j++) {
  124. XWPFParagraph cellParagraph = cellList.get(j).getParagraphArray(0);
  125. XWPFRun cellParagraphRun = cellParagraph.getRuns().get(0);
  126. cellParagraphRun.setText(String.valueOf(list.get(j)));
  127. }
  128. }
  129. }
  130. }

   下面是用到的工具类:                                         

  1. package cn.hxc.myWorld.util;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.OutputStream;
  9. import java.math.BigInteger;
  10. import java.util.List;
  11. import java.util.logging.Level;
  12. import java.util.logging.Logger;
  13.  
  14. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  15. import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
  16. import org.apache.poi.xwpf.usermodel.TextAlignment;
  17. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  18. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  19. import org.apache.poi.xwpf.usermodel.XWPFPicture;
  20. import org.apache.poi.xwpf.usermodel.XWPFPictureData;
  21. import org.apache.poi.xwpf.usermodel.XWPFRelation;
  22. import org.apache.poi.xwpf.usermodel.XWPFRun;
  23. import org.apache.poi.xwpf.usermodel.XWPFTable;
  24. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  25. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  26. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
  27. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
  28. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
  29. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
  30. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
  31. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
  32. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
  33. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
  34. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
  35.  
  36. import cn.hxc.myWorld.domain.ParagraphStyle;
  37. import cn.hxc.myWorld.domain.TextStyle;
  38.  
  39. /**
  40. * @Description 设置docx文档的样式及一些操作
  41. * @Author Huangxiaocong
  42. * 2018年12月1日 下午12:18:41
  43. * 基本概念说明:XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档
  44. * XWPFParagraph代表文档、表格、标题等种的段落,由多个XWPFRun组成
  45. * XWPFRun代表具有同样风格的一段文本
  46. * XWPFTable代表一个表格
  47. * XWPFTableRow代表表格的一行
  48. * XWPFTableCell代表表格的一个单元格
  49. * XWPFChar 表示.docx文件中的图表
  50. * XWPFHyperlink 表示超链接
  51. * XWPFPicture 代表图片
  52. *
  53. * 注意:直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun。
  54. */
  55. public class XWPFHelper {
  56. private static Logger logger = Logger.getLogger(XWPFHelper.class.toString());
  57.  
  58. /**
  59. * 创建一个word对象
  60. * @return
  61. * @Author Huangxiaocong 2018年12月1日 上午11:56:35
  62. */
  63. public XWPFDocument createDocument() {
  64. XWPFDocument document = new XWPFDocument();
  65. return document;
  66. }
  67. /**
  68. * 打开word文档
  69. * @param path 文档所在路径
  70. * @return
  71. * @throws IOException
  72. * @Author Huangxiaocong 2018年12月1日 下午12:30:07
  73. */
  74. public XWPFDocument openDoc(String path) throws IOException {
  75. InputStream is = new FileInputStream(path);
  76. return new XWPFDocument(is);
  77. }
  78. /**
  79. * 保存word文档
  80. * @param document 文档对象
  81. * @param savePath 保存路径
  82. * @throws IOException
  83. * @Author Huangxiaocong 2018年12月1日 下午12:32:37
  84. */
  85. public void saveDocument(XWPFDocument document, String savePath) throws IOException {
  86. OutputStream os = new FileOutputStream(savePath);
  87. document.write(os);
  88. os.close();
  89. }
  90. /**
  91. * 设置段落文本样式 设置超链接及样式
  92. * @param paragraph
  93. * @param textStyle
  94. * @param url
  95. * @Author Huangxiaocong 2018年12月1日 下午3:56:32
  96. */
  97. public void addParagraphTextHyperlink(XWPFParagraph paragraph, TextStyle textStyle) {
  98. String id = paragraph.getDocument().getPackagePart().
  99. addExternalRelationship(textStyle.getUrl(),
  100. XWPFRelation.HYPERLINK.getRelation()).getId();
  101. //追加链接并将其绑定到关系中
  102. CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();
  103. cLink.setId(id);
  104. //创建链接文本
  105. CTText ctText = CTText.Factory.newInstance();
  106. ctText.setStringValue(textStyle.getText());
  107. CTR ctr = CTR.Factory.newInstance();
  108. CTRPr rpr = ctr.addNewRPr();
  109. //以下设置各种样式 详情看TextStyle类
  110. if(textStyle.getFontFamily() != "" && textStyle.getFontFamily() != null ) {
  111. CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
  112. fonts.setAscii(textStyle.getFontFamily());
  113. //...
  114. }
  115. //设置字体大小
  116. }
  117. /**
  118. * 设置段落的基本样式 设置段落间距信息, 一行 = 100 一磅=20
  119. * @param paragraph
  120. * @param paragStyle
  121. * @Author Huangxiaocong 2018年12月1日 下午4:27:17
  122. */
  123. public void setParagraphSpacingInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle, STLineSpacingRule.Enum lineValue) {
  124. CTPPr pPPr = getParagraphCTPPr(paragraph);
  125. CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr.getSpacing() : pPPr.addNewSpacing();
  126. if(paragStyle.isSpace()) {
  127. //段前磅数
  128. if(paragStyle.getBefore() != null) {
  129. pSpacing.setBefore(new BigInteger(paragStyle.getBefore()));
  130. }
  131. //段后磅数
  132. if(paragStyle.getAfter() != null) {
  133. pSpacing.setAfter(new BigInteger(paragStyle.getAfter()));
  134. }
  135. //依次设置段前行数、段后行数
  136. //...
  137. }
  138. //间距
  139. if(paragStyle.isLine()) {
  140. if(paragStyle.getLine() != null) {
  141. pSpacing.setLine(new BigInteger(paragStyle.getLine()));
  142. }
  143. if(lineValue != null) {
  144. pSpacing.setLineRule(lineValue); //
  145. }
  146. }
  147. }
  148. /**
  149. * 设置段落缩进信息 1厘米 约等于 567
  150. * @param paragraph
  151. * @param paragStyle
  152. * @Author Huangxiaocong 2018年12月1日 下午7:59:35
  153. */
  154. public void setParagraphIndInfo(XWPFParagraph paragraph, ParagraphStyle paragStyle) {
  155. CTPPr pPPr = getParagraphCTPPr(paragraph);
  156. CTInd pInd = pPPr.getInd() != null ? pPPr.getInd() : pPPr.addNewInd();
  157. if(paragStyle.getFirstLine() != null) {
  158. pInd.setFirstLine(new BigInteger(paragStyle.getFirstLine()));
  159. }
  160. //再进行其他设置
  161. //...
  162. }
  163. /**
  164. * 设置段落对齐 方式
  165. * @param paragraph
  166. * @param pAlign
  167. * @param valign
  168. * @Author Huangxiaocong 2018年12月1日 下午8:54:43
  169. */
  170. public void setParagraphAlignInfo(XWPFParagraph paragraph, ParagraphAlignment pAlign, TextAlignment valign) {
  171. if(pAlign != null) {
  172. paragraph.setAlignment(pAlign);
  173. }
  174. if(valign != null) {
  175. paragraph.setVerticalAlignment(valign);
  176. }
  177. }
  178. /**
  179. * 得到段落的CTPPr
  180. * @param paragraph
  181. * @return
  182. * @Author Huangxiaocong 2018年12月1日 下午7:36:10
  183. */
  184. public CTPPr getParagraphCTPPr(XWPFParagraph paragraph) {
  185. CTPPr pPPr = null;
  186. if(paragraph.getCTP() != null) {
  187. if(paragraph.getCTP().getPPr() != null) {
  188. pPPr = paragraph.getCTP().getPPr();
  189. } else {
  190. pPPr = paragraph.getCTP().addNewPPr();
  191. }
  192. }
  193. return pPPr;
  194. }
  195. /**
  196. * 得到XWPFRun的CTRPr
  197. * @param paragraph
  198. * @param pRun
  199. * @return
  200. * @Author Huangxiaocong 2018年12月1日 下午7:46:01
  201. */
  202. public CTRPr getRunCTRPr(XWPFParagraph paragraph, XWPFRun pRun) {
  203. CTRPr ctrPr = null;
  204. if(pRun.getCTR() != null) {
  205. ctrPr = pRun.getCTR().getRPr();
  206. if(ctrPr == null) {
  207. ctrPr = pRun.getCTR().addNewRPr();
  208. }
  209. } else {
  210. ctrPr = paragraph.getCTP().addNewR().addNewRPr();
  211. }
  212. return ctrPr;
  213. }
  214.  
  215. /**
  216. * 复制表格
  217. * @param targetTable
  218. * @param sourceTable
  219. * @Author Huangxiaocong 2018年12月1日 下午1:40:01
  220. */
  221. public void copyTable(XWPFTable targetTable, XWPFTable sourceTable) {
  222. //复制表格属性
  223. targetTable.getCTTbl().setTblPr(sourceTable.getCTTbl().getTblPr());
  224. //复制行
  225. for(int i = 0; i < sourceTable.getRows().size(); i++) {
  226. XWPFTableRow targetRow = targetTable.getRow(i);
  227. XWPFTableRow sourceRow = sourceTable.getRow(i);
  228. if(targetRow == null) {
  229. targetTable.addRow(sourceRow);
  230. } else {
  231. copyTableRow(targetRow, sourceRow);
  232. }
  233. }
  234. }
  235. /**
  236. * 复制单元格
  237. * @param targetRow
  238. * @param sourceRow
  239. * @Author Huangxiaocong 2018年12月1日 下午1:33:22
  240. */
  241. public void copyTableRow(XWPFTableRow targetRow, XWPFTableRow sourceRow) {
  242. //复制样式
  243. if(sourceRow != null) {
  244. targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
  245. }
  246. //复制单元格
  247. for(int i = 0; i < sourceRow.getTableCells().size(); i++) {
  248. XWPFTableCell tCell = targetRow.getCell(i);
  249. XWPFTableCell sCell = sourceRow.getCell(i);
  250. if(tCell == sCell) {
  251. tCell = targetRow.addNewTableCell();
  252. }
  253. copyTableCell(tCell, sCell);
  254. }
  255. }
  256. /**
  257. * 复制单元格(列) 从sourceCell到targetCell
  258. * @param targetCell
  259. * @param sourceCell
  260. * @Author Huangxiaocong 2018年12月1日 下午1:27:38
  261. */
  262. public void copyTableCell(XWPFTableCell targetCell, XWPFTableCell sourceCell) {
  263. //表格属性
  264. if(sourceCell.getCTTc() != null) {
  265. targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
  266. }
  267. //删除段落
  268. for(int pos = 0; pos < targetCell.getParagraphs().size(); pos++) {
  269. targetCell.removeParagraph(pos);
  270. }
  271. //添加段落
  272. for(XWPFParagraph sourceParag : sourceCell.getParagraphs()) {
  273. XWPFParagraph targetParag = targetCell.addParagraph();
  274. copyParagraph(targetParag, sourceParag);
  275. }
  276. }
  277. /**
  278. * 复制段落,从sourceParag到targetParag
  279. * @param targetParag
  280. * @param sourceParag
  281. * @Author Huangxiaocong 2018年12月1日 下午1:16:26
  282. */
  283. public void copyParagraph(XWPFParagraph targetParag, XWPFParagraph sourceParag) {
  284. targetParag.getCTP().setPPr(sourceParag.getCTP().getPPr()); //设置段落样式
  285. //移除所有的run
  286. for(int pos = targetParag.getRuns().size() - 1; pos >= 0; pos-- ) {
  287. targetParag.removeRun(pos);
  288. }
  289. //copy新的run
  290. for(XWPFRun sRun : sourceParag.getRuns()) {
  291. XWPFRun tarRun = targetParag.createRun();
  292. copyRun(tarRun, sRun);
  293. }
  294. }
  295. /**
  296. * 复制XWPFRun 从sourceRun到targetRun
  297. * @param targetRun
  298. * @param sourceRun
  299. * @Author Huangxiaocong 2018年12月1日 下午12:56:53
  300. */
  301. public void copyRun(XWPFRun targetRun, XWPFRun sourceRun) {
  302. //设置targetRun属性
  303. targetRun.getCTR().setRPr(sourceRun.getCTR().getRPr());
  304. targetRun.setText(sourceRun.text());//设置文本
  305. //处理图片
  306. List<XWPFPicture> pictures = sourceRun.getEmbeddedPictures();
  307. for(XWPFPicture picture : pictures) {
  308. try {
  309. copyPicture(targetRun, picture);
  310. } catch (InvalidFormatException e) {
  311. e.printStackTrace();
  312. logger.log(Level.WARNING, "copyRun", e);
  313. } catch (IOException e) {
  314. e.printStackTrace();
  315. logger.log(Level.WARNING, "copyRun", e);
  316. }
  317. }
  318. }
  319. /**
  320. * 复制图片从sourcePicture到 targetRun(XWPFPicture --> XWPFRun)
  321. * @param targetRun
  322. * @param source
  323. * @throws IOException
  324. * @throws InvalidFormatException
  325. * @Author Huangxiaocong 2018年12月1日 下午12:57:33
  326. */
  327. public void copyPicture(XWPFRun targetRun, XWPFPicture sourcePicture) throws InvalidFormatException, IOException {
  328. XWPFPictureData picData = sourcePicture.getPictureData();
  329. String fileName = picData.getFileName(); //图片的名称
  330. InputStream picInIsData = new ByteArrayInputStream(picData.getData());
  331. int picType = picData.getPictureType();
  332. int width = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCx();
  333. int height = (int) sourcePicture.getCTPicture().getSpPr().getXfrm().getExt().getCy();
  334. targetRun.addPicture(picInIsData, picType, fileName, width, height);
  335. // targetRun.addBreak();//分行
  336. }
  337. }

    工具类二:    

  1. package cn.hxc.myWorld.util;
  2.  
  3. import java.math.BigInteger;
  4. import java.util.ArrayList;
  5. import java.util.Iterator;
  6. import java.util.List;
  7.  
  8. import org.apache.poi.xwpf.usermodel.BodyElementType;
  9. import org.apache.poi.xwpf.usermodel.IBodyElement;
  10. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  11. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  12. import org.apache.poi.xwpf.usermodel.XWPFRun;
  13. import org.apache.poi.xwpf.usermodel.XWPFTable;
  14. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  15. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  16. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
  17. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
  18. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
  19. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
  20. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
  21. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
  22. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
  23. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
  24. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
  25. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
  26. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
  27. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
  28. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
  29. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
  30. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
  31. import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
  32.  
  33. /**
  34. * @Description 操作word的基本工具类
  35. * 2018年12月3日 上午11:12:18
  36. * @Author Huangxiaocong
  37. */
  38. public class XWPFHelperTable {
  39.  
  40. /**
  41. * 删除指定位置的表格,被删除表格后的索引位置
  42. * @param document
  43. * @param pos
  44. * @Author Huangxiaocong 2018年12月1日 下午10:32:43
  45. */
  46. public void deleteTableByIndex(XWPFDocument document, int pos) {
  47. Iterator<IBodyElement> bodyElement = document.getBodyElementsIterator();
  48. int eIndex = 0, tableIndex = -1;
  49. while(bodyElement.hasNext()) {
  50. IBodyElement element = bodyElement.next();
  51. BodyElementType elementType = element.getElementType();
  52. if(elementType == BodyElementType.TABLE) {
  53. tableIndex++;
  54. if(tableIndex == pos) {
  55. break;
  56. }
  57. }
  58. eIndex++;
  59. }
  60. document.removeBodyElement(eIndex);
  61. }
  62. /**
  63. * 获得指定位置的表格
  64. * @param document
  65. * @param index
  66. * @return
  67. * @Author Huangxiaocong 2018年12月1日 下午10:34:14
  68. */
  69. public XWPFTable getTableByIndex(XWPFDocument document, int index) {
  70. List<XWPFTable> tableList = document.getTables();
  71. if(tableList == null || index < 0 || index > tableList.size()) {
  72. return null;
  73. }
  74. return tableList.get(index);
  75. }
  76. /**
  77. * 得到表格的内容(第一次跨行单元格视为一个,第二次跳过跨行合并的单元格)
  78. * @param table
  79. * @return
  80. * @Author Huangxiaocong 2018年12月1日 下午10:46:41
  81. */
  82. public List<List<String>> getTableRConten(XWPFTable table) {
  83. List<List<String>> tableContextList = new ArrayList<List<String>>();
  84. for(int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
  85. XWPFTableRow row = table.getRow(rowIndex);
  86. List<String> cellContentList = new ArrayList<String>();
  87. for(int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++ ) {
  88. XWPFTableCell cell = row.getCell(colIndex);
  89. CTTc ctTc = cell.getCTTc();
  90. if(ctTc.isSetTcPr()) {
  91. CTTcPr tcPr = ctTc.getTcPr();
  92. if(tcPr.isSetHMerge()) {
  93. CTHMerge hMerge = tcPr.getHMerge();
  94. if(STMerge.RESTART.equals(hMerge.getVal())) {
  95. cellContentList.add(getTableCellContent(cell));
  96. }
  97. } else if(tcPr.isSetVMerge()) {
  98. CTVMerge vMerge = tcPr.getVMerge();
  99. if(STMerge.RESTART.equals(vMerge.getVal())) {
  100. cellContentList.add(getTableCellContent(cell));
  101. }
  102. } else {
  103. cellContentList.add(getTableCellContent(cell));
  104. }
  105. }
  106. }
  107. tableContextList.add(cellContentList);
  108. }
  109. return tableContextList;
  110. }
  111.  
  112. /**
  113. * 获得一个表格的单元格的内容
  114. * @param cell
  115. * @return
  116. * @Author Huangxiaocong 2018年12月2日 下午7:39:23
  117. */
  118. public String getTableCellContent(XWPFTableCell cell) {
  119. StringBuffer sb = new StringBuffer();
  120. List<XWPFParagraph> cellParagList = cell.getParagraphs();
  121. if(cellParagList != null && cellParagList.size() > 0) {
  122. for(XWPFParagraph xwpfPr: cellParagList) {
  123. List<XWPFRun> runs = xwpfPr.getRuns();
  124. if(runs != null && runs.size() > 0) {
  125. for(XWPFRun xwpfRun : runs) {
  126. sb.append(xwpfRun.getText(0));
  127. }
  128. }
  129. }
  130. }
  131. return sb.toString();
  132. }
  133. /**
  134. * 得到表格内容,合并后的单元格视为一个单元格
  135. * @param table
  136. * @return
  137. * @Author Huangxiaocong 2018年12月2日 下午7:47:19
  138. */
  139. public List<List<String>> getTableContent(XWPFTable table) {
  140. List<List<String>> tableContentList = new ArrayList<List<String>>();
  141. for (int rowIndex = 0, rowLen = table.getNumberOfRows(); rowIndex < rowLen; rowIndex++) {
  142. XWPFTableRow row = table.getRow(rowIndex);
  143. List<String> cellContentList = new ArrayList<String>();
  144. for (int colIndex = 0, colLen = row.getTableCells().size(); colIndex < colLen; colIndex++) {
  145. XWPFTableCell cell = row.getCell(colIndex);
  146. cellContentList.add(getTableCellContent(cell));
  147. }
  148. tableContentList.add(cellContentList);
  149. }
  150. return tableContentList;
  151. }
  152.  
  153. /**
  154. * 跨列合并
  155. * @param table
  156. * @param row 所合并的行
  157. * @param fromCell 起始列
  158. * @param toCell 终止列
  159. * @Description
  160. * @Author Huangxiaocong 2018年11月26日 下午9:23:22
  161. */
  162. public void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
  163. for(int cellIndex = fromCell; cellIndex <= toCell; cellIndex++ ) {
  164. XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
  165. if(cellIndex == fromCell) {
  166. cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
  167. } else {
  168. cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
  169. }
  170. }
  171. }
  172. /**
  173. * 跨行合并
  174. * @param table
  175. * @param col 合并的列
  176. * @param fromRow 起始行
  177. * @param toRow 终止行
  178. * @Description
  179. * @Author Huangxiaocong 2018年11月26日 下午9:09:19
  180. */
  181. public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
  182. for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
  183. XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
  184. //第一个合并单元格用重启合并值设置
  185. if(rowIndex == fromRow) {
  186. cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
  187. } else {
  188. //合并第一个单元格的单元被设置为“继续”
  189. cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
  190. }
  191. }
  192. }
  193.  
  194. /**
  195. * @Description: 创建表格,创建后表格至少有1行1列,设置列宽
  196. */
  197. public XWPFTable createTable(XWPFDocument xdoc, int rowSize, int cellSize,
  198. boolean isSetColWidth, int[] colWidths) {
  199. XWPFTable table = xdoc.createTable(rowSize, cellSize);
  200. if (isSetColWidth) {
  201. CTTbl ttbl = table.getCTTbl();
  202. CTTblGrid tblGrid = ttbl.addNewTblGrid();
  203. for (int j = 0, len = Math.min(cellSize, colWidths.length); j < len; j++) {
  204. CTTblGridCol gridCol = tblGrid.addNewGridCol();
  205. gridCol.setW(new BigInteger(String.valueOf(colWidths[j])));
  206. }
  207. }
  208. return table;
  209. }
  210.  
  211. /**
  212. * @Description: 设置表格总宽度与水平对齐方式
  213. */
  214. public void setTableWidthAndHAlign(XWPFTable table, String width,
  215. STJc.Enum enumValue) {
  216. CTTblPr tblPr = getTableCTTblPr(table);
  217. // 表格宽度
  218. CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
  219. if (enumValue != null) {
  220. CTJc cTJc = tblPr.addNewJc();
  221. cTJc.setVal(enumValue);
  222. }
  223. // 设置宽度
  224. tblWidth.setW(new BigInteger(width));
  225. tblWidth.setType(STTblWidth.DXA);
  226. }
  227.  
  228. /**
  229. * @Description: 得到Table的CTTblPr,不存在则新建
  230. */
  231. public CTTblPr getTableCTTblPr(XWPFTable table) {
  232. CTTbl ttbl = table.getCTTbl();
  233. // 表格属性
  234. CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
  235. return tblPr;
  236. }
  237.  
  238. /**
  239. * 设置表格行高
  240. * @param infoTable
  241. * @param heigth 高度
  242. * @param vertical 表格内容的显示方式:居中、靠右...
  243. * @Author Huangxiaocong 2018年12月16日
  244. */
  245. public void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
  246. List<XWPFTableRow> rows = infoTable.getRows();
  247. for(XWPFTableRow row : rows) {
  248. CTTrPr trPr = row.getCtRow().addNewTrPr();
  249. CTHeight ht = trPr.addNewTrHeight();
  250. ht.setVal(BigInteger.valueOf(heigth));
  251. List<XWPFTableCell> cells = row.getTableCells();
  252. for(XWPFTableCell tableCell : cells ) {
  253. CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
  254. cttcpr.addNewVAlign().setVal(vertical);
  255. }
  256. }
  257. }
  258. }

   实体类(自己填写get/set方法):                   

  1. /**
  2. * @Description 文本样式
  3. * 2018年12月1日 下午4:09:30
  4. * @Author Huangxiaocong
  5. */
  6. public class TextStyle {
  7.  
  8. private String url; // 超链接
  9. private String text; //文本内容
  10. private String fontFamily; //字体
  11. private String fontSize; //字体大小
  12. private String colorVal; //字体颜色
  13. private String shdColor; //底纹颜色
  14. private int position; //文本位置
  15. private int spacingValue; //间距
  16. private int indent; //缩进
  17. private boolean isBlod; //加粗
  18. private boolean isUnderLine; //下划线
  19. private boolean underLineColor; //
  20. private boolean isItalic; //倾斜
  21. private boolean isStrike; //删除线
  22. private boolean isDStrike; //双删除线
  23. private boolean isShadow; //阴影
  24. private boolean isVanish; //隐藏
  25. private boolean isEmboss; //阳文
  26. private boolean isImprint; //阴文
  27. private boolean isOutline; //空心
  28. private boolean isHightLight; //突出显示文本
  29. private boolean isShd; //底纹
  30.  
  31. //此处省略get/set方法...
  32.  
  33. }
  1. /**
  2. * @Description 段落样式
  3. * 2018年12月1日 下午4:20:05
  4. * @Author Huangxiaocong
  5. */
  6. public class ParagraphStyle {
  7.  
  8. private boolean isSpace; //是否缩进
  9. private String before; //段前磅数
  10. private String after; //段后磅数
  11. private String beforeLines; //段前行数
  12. private String afterLines; //段后行数
  13. private boolean isLine; //是否间距
  14. private String line; //间距距离
  15. //段落缩进信息
  16. private String firstLine;
  17. private String firstLineChar;
  18. private String hanging;
  19. private String hangingChar;
  20. private String right;
  21. private String rightChar;
  22. private String left;
  23. private String leftChar;
  24.  
  25. //此处省略get/set方法...
  26. }

   最后是测试类:    

  1. package cn.hxc.myWorld.test;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  9.  
  10. import cn.hxc.myWorld.myWorld.ExportWord;
  11.  
  12. public class TestExportWord {
  13.  
  14. public static void main(String[] args) throws Exception {
  15. ExportWord ew = new ExportWord();
  16. XWPFDocument document = ew.createXWPFDocument();
  17. List<List<Object>> list = new ArrayList<List<Object>>();
  18.  
  19. List<Object> tempList = new ArrayList<Object>();
  20. tempList.add("姓名");
  21. tempList.add("黄xx");
  22. tempList.add("性别");
  23. tempList.add("男");
  24. tempList.add("出生日期");
  25. tempList.add("2018-10-10");
  26. list.add(tempList);
  27. tempList = new ArrayList<Object>();
  28. tempList.add("身份证号");
  29. tempList.add("36073xxxxxxxxxxx");
  30. list.add(tempList);
  31. tempList = new ArrayList<Object>();
  32. tempList.add("出生地");
  33. tempList.add("江西");
  34. tempList.add("名族");
  35. tempList.add("汉");
  36. tempList.add("婚否");
  37. tempList.add("否");
  38. list.add(tempList);
  39. tempList = new ArrayList<Object>();
  40. tempList.add("既往病史");
  41. tempList.add("无");
  42. list.add(tempList);
  43.  
  44. Map<String, Object> dataList = new HashMap<String, Object>();
  45. dataList.put("TITLE", "个人体检表");
  46. dataList.put("TABLEDATA", list);
  47. ew.exportCheckWord(dataList, document, "E:/expWordTest.docx");
  48. System.out.println("文档生成成功");
  49. }
  50. }

效果如图:

总的制作完毕。

关于导出Word的另一种方案:https://www.cnblogs.com/sun-flower1314/p/10126111.html 

好累呀 确定不点个赞?(<微笑^^>)

同时 希望各位能提出宝贵的意见方便改进 不甚感激!!

使用POI导出Word(含表格)的实现方式及操作Word的工具类的更多相关文章

  1. java里poi操作excel的工具类(兼容各版本)

    转: java里poi操作excel的工具类(兼容各版本) 下面是文件内具体内容,文件下载: import java.io.FileNotFoundException; import java.io. ...

  2. poi导出word表格详解 超详细了

    转:非常感谢原作者 poi导出word表格详解 2018年07月20日 10:41:33 Z丶royAl 阅读数:36138   一.效果如下 二.js代码 function export_word( ...

  3. poi报表导出4.1.0版本工具类 导出并下载

    这一段时间,由于项目上线基于稳定,所以我这边在基于我们一期迭代的分支上优化一部分我们之前没有做的功能,报表导出.本身之前用的是3.5的版本,但是由于同事要写导入,写的代码只有4.1.0的版本支持,所以 ...

  4. spring boot 整合 poi 导出excel

    一. 第一种方式 1.首先从中央仓库中导入架包Poi3.14以及Poi-ooxml3.14. <dependency> <groupId>org.apache.poi</ ...

  5. POI导出时写一份到ftp服务器,一份下载给客户端

    导语: 昨天接到项目经理这么一个需求,让我在POI导出Excel的时候写一份到我之前搭建的ftp服务器上.所以就有了这篇博客首先我们来分析下之前的业务逻辑:我们创建并构造了一个workbook,然后构 ...

  6. java实现Excel定制导出(基于POI的工具类)

    我的需求: 项目中有一些工程表格需要导出,设计到行列合并,定制样式,原有工具类冗余,内聚性强.所以想写一个可以随意定制excel的工具类,工具类满足需求: 对于常用的工程表格有模板格式,可以任意插拔. ...

  7. Python操作Word:常用对象介绍

    前面已经介绍过了试用win32com类库来进行Word开发,系列文章<Python操作Word>是继承了前面的文章,所以,你应该先查看前面的文章,其实只有两篇,文章地址列在最下面的参考资料 ...

  8. C#/VB.NET 操作Word批注(二)——如何插入图片、读取、回复Word批注内容

    序 在前面的文章C# 如何插入.修改.删除Word批注一文中介绍了如何操作Word批注的一些方法,在本篇文章中继续介绍操作Word批注的方法.分以下三种情况来介绍: 1. 插入图片到Word批注 2. ...

  9. Java 借助poi操作PDF工具类

    ​ 一直以来说写一个关于Java操作PDF的工具类,也没有时间去写,今天抽空写一个简单的工具类,拥有PDF中 换行,字体大小,字体设置,字体颜色,首行缩进,居中,居左,居右,增加新一页等功能,如果需要 ...

随机推荐

  1. Flask(1)- 简介

    背景 为啥要学,很久之前就学过点,没写文章 最近因为要写机器人工具,其实就是简单的纯服务端工具 反正 flask 也挺简单,一天快速过完 概念会直接搬教程的,实操自己敲一遍再总结 参考教程 https ...

  2. CentOS 8 按tab键不能自动补全问题解决方案

    CentOS中按tab键不能自动补全问题解决办法 检查一下系统有没有安装bash-completion包 [root@Sonarqube ~]# rpm -lq bash-completion yum ...

  3. 以对话的形式管理你的Kubernetes集群

    BotKube BotKube 是一个用于监控和调试 Kubernetes 集群的消息传递工具. BotKube 可以与多个消息传递平台(如 Slack.Mattermost 或 Microsoft ...

  4. mysql中比较字符串类型数字

    操作的表: p.p1 { margin: 0; font: 16px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures ...

  5. bash的RANDOM变量生成的是真正的随机数吗

    static void seedrand () { struct timeval tv; gettimeofday (&tv, NULL); sbrand (tv.tv_sec ^ tv.tv ...

  6. 2012年第三届蓝桥杯C/C++程序设计本科B组省赛 密码发生器

    密码发生器 题目描述: ```bash 在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全:如果设置不好记的密码,又担心自己也会忘记:如果写在纸上, ...

  7. 使用Flyway来管理数据库版本

    使用Flyway来管理数据库版本 Flyway是什么 Flyway是一款数据库迁移(migration)工具. 它可以帮助我们在不同环境保持数据库的同步,减少手工操作,避免数据导入的顺序错误,同时也减 ...

  8. SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!

    大家好,我是飘渺. 今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常. 首先我们来看看为什么要返回统一的标准格式? 为什么要对Sp ...

  9. Linux_multipath

    安装多路径软件 yum功能安装一下软件包 yum -y install device-mapper device-mapper-multipath 修改多路径软件运行等级为开机自启 chkconfig ...

  10. 个人博客开发之blog-api 项目全局日志拦截记录

    前言 大型完善项目中肯定是需要一个全局日志拦截,记录每次接口访问相关信息,包括: 访问ip,访问设备,请求参数,响应结果,响应时间,开始请求时间,访问接口描述,访问的用户,接口地址,请求类型,便于项目 ...