文章目录

  • poi-tl 入门示例
    • 1.准备word模板
    • 2.代码
  • 自定义列表序号
    • 1. poi-tl 支持的序号列表,直接使用文档种说明即可
    • 2. 要是没有,可以利用NumberingFormat类去生成指定的样式;例如生成 a) b)的序号
    • 3. 同样按照官方api指定{{*var}}后
    • 4. 具体代码如下
  • 自定义表格宽度和表格合并
    • 1. 在word模板文件中,生成表格位置添加标签:**{{#check_table}}**
    • 2. 具体整体代码如下
    • 3. 设置表格宽度 setTableRenderDataAndColWidth
    • 4. 表格合并方法 mergeCell
  • 自定义标题
    • 1. word模板内容如下
    • 3. 需要生成的标题按照md文件格式拼接为字符串即可
    • 生成标题其他注意点
      • 1. 自己指定生成标题序号开始位置:重写DocumentVisitor.class 类
      • 2. 自动生成标题的样式,也可以按照自己想要的方式设置
  • 更新目录 (wps 不支持,只支持office)
    • 网上搜到的方式,直接采用该方法,可以生成并且更新目录
    • poi-tl的方式
      • word模板添加标签 {{TOC}}
      • 代码如下
    • 也可以word已经生成目录,后面只是修改了添加标题,去更新目录

poi-tl 入门示例

可参照poi-tl 官方api文档:poi-tl
引入maven 后

                         <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.11.0</version></dependency>

1.准备word模板

2.代码

  public class PoiTest {public static void main(String[] args) throws IOException {//要写入模板的数据Map<String,Object> exampleData = new HashMap<>();exampleData.put("username","admin");exampleData.put("password","123456");FileInputStream inputStream = new FileInputStream("D:/test_word/example1.docx");XWPFTemplate template = XWPFTemplate.compile(inputStream).render(exampleData);//文件输出流FileOutputStream out = new FileOutputStream("D:/test_word/example1.docx");template.write(out);out.flush();out.close();template.close();}
}

自定义列表序号

1. poi-tl 支持的序号列表,直接使用文档种说明即可

2. 要是没有,可以利用NumberingFormat类去生成指定的样式;例如生成 a) b)的序号

3. 同样按照官方api指定{{*var}}后

4. 具体代码如下

public class test {public static void main(String[] args) throws IOException {//要写入模板的数据Map<String, Object> datas1 = new HashMap<String, Object>();//列表集合List<String> varList = Arrays.asList("序号1","序号2");//自定义序号的样式为  a)  b)  c)NumberingFormat.Builder builder = NumberingFormat.builder("%{0})") //%{0}) 可以指定自己需要的样式.withNumFmt(NumFormat.LOWER_LETTER);  //小写字母NumberingFormat numberingFormat = builder.build(0);Numberings.NumberingBuilder of = Numberings.of(numberingFormat);//a)  b)  c)//列表 数据赋值varList.forEach(s -> of.addItem(s));NumberingRenderData numberingRenderData = of.create();datas1.put("var", numberingRenderData);XWPFTemplate.compile("D:/test_word/test.docx").render(datas1).writeToFile("D:/test_word/test1.docx");}
}

自定义表格宽度和表格合并

poi-tl导出的word表格默认宽度是自适应的,若是想要指定列的宽度增加,可以采用如下方式:
最终实现的word表格

1. 在word模板文件中,生成表格位置添加标签:{{#check_table}}

2. 具体整体代码如下

 public class test {public static void main(String[] args) throws IOException {Map<String, Object> datas = new HashMap<String, Object>();// create table//word的 表格List tableList = new ArrayList<>();tableList.add("数据1");tableList.add("数据2");tableList.add("数据3");tableList.add("数据4");tableList.add("数据5");tableList.add("数据6");//验证类型集合List<String> typeList = Arrays.asList("MC0","MC1","MC2","MC3","MC4","MC5","MC6","MC7","MC8","MC9");//表头是两行//第一行数据是固定内容 "序号", "章节号", "项目", "内容", "验证方法", "备注"List<String> headerCellListTemp1 = Arrays.asList("序号", "章节号", "项目", "内容", "验证方法");List<String> headerCellList1 = new ArrayList<>(headerCellListTemp1);//验证方法,可能是多列数据  第一列是验证方法,后面是赋空字符串,用于合并单元格;//数据类型:验证方法 "" "" ""//验证类型长度int typeListSize = typeList.size();for (int k = 0; k < typeListSize - 1; k++) {headerCellList1.add(" "); //赋空字符串}headerCellList1.add("备注");String[] headerCell1 = headerCellList1.toArray(new String[headerCellList1.size()]);RowRenderData header1 = Rows.of(headerCell1).center().create();//headerCell2 :验证方法对应列,是动态内容List<String> headerCellListTemp2 = Arrays.asList("序号", "章节号", "项目", "内容");List<String> headerCellList2 = new ArrayList<>(headerCellListTemp2);// 验证方法对应列headerCellList2.addAll(typeList);//备注对应的列 赋空值headerCellList2.add(" ");String[] headerCell2 = headerCellList2.toArray(new String[headerCellList2.size()]);RowRenderData header2 = Rows.of(headerCell2).center().create();//表格 列的数量int cellLength = headerCell1.length;//无数据只有表头数据 tableList 无值if (CollectionUtil.isEmpty(tableList)) {RowRenderData[] RowRenderDataHeader = new RowRenderData[2];RowRenderDataHeader[0] = header1;RowRenderDataHeader[1] = header2;TableRenderData check_table = setTableRenderDataAndColWidth(RowRenderDataHeader, cellLength);// table 只有表头数据datas.put("check_table", check_table);} else {int length = 2 + tableList.size();//行数据 数组RowRenderData[] RowRenderData = new RowRenderData[length];RowRenderData[0] = header1;RowRenderData[1] = header2;for (int i = 0; i < tableList.size(); i++) {String index = Integer.toString(i + 1);List<String> tempList = Arrays.asList("A", "B", "C","D", "E", "F", "G", "H", "I", "G");String[] cellString = new String[cellLength];cellString[0] = index; //序号cellString[1] = "5.1.1";//标题序号cellString[2] = "项目"; // 项目cellString[3] = "说明"; //内容 : 描述//验证方法对应数据赋值if (headerCell2.length > 4) {for (int j = 0; j < tempList.size(); j++) {cellString[j + 4] = tempList.get(j);}}//备注cellString[cellLength - 1] = "备注";RowRenderData rowRenderData = Rows.of(cellString).center().create();//行数据赋值RowRenderData[2 + i] = rowRenderData;}TableRenderData check_table = setTableRenderDataAndColWidth(RowRenderData, cellLength);// tabledatas.put("check_table", check_table);}XWPFTemplate.compile("D:/test_word/test.docx").render(datas).writeToFile("D:/test_word/test1.docx");}/*** 表格赋值,* 设置列宽和合并单元格** @param rowRenderDataArray* @param cellLength* @return*/private static TableRenderData setTableRenderDataAndColWidth(RowRenderData[] rowRenderDataArray, Integer cellLength) {//table赋值set方法需要listList<RowRenderData> RowRenderDataList = Arrays.asList(rowRenderDataArray);//设置列宽:double[] colWidthsCm = new double[cellLength];for (int i = 0; i < cellLength; i++) {// "章节号", "项目", "内容" 设置为 2if (i == 1 || i == 2 || i == 3) {colWidthsCm[i] = 2D;} else {colWidthsCm[i] = 1D;}}//18.450000762939453D A4纸张TableRenderData check_table = Tables.ofWidth(18.450000762939453D, colWidthsCm).center().create();check_table.setRows(RowRenderDataList);//合并单元格MergeCellRule.MergeCellRuleBuilder mergeCellRuleBuilder = mergeCell(cellLength);check_table.setMergeRule(mergeCellRuleBuilder.build());return check_table;}/*** 表格 合并单元格** @param cellLength* @return*/private static MergeCellRule.MergeCellRuleBuilder mergeCell(Integer cellLength) {/*** 设置表格合并规则 从0开始* 1.起始行 MergeCellRule.Grid.of(i, j) i: 行 j: 列* 2.结束行 MergeCellRule.Grid.of(i, j) i: 行 j: 列*///合并单元格//合并到【备注】前一列MergeCellRule.MergeCellRuleBuilder mergeCellRuleBuilder = MergeCellRule.builder();mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 0), MergeCellRule.Grid.of(1, 0));//序号合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 1), MergeCellRule.Grid.of(1, 1));//章节号合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 2), MergeCellRule.Grid.of(1, 2));//项目合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 3), MergeCellRule.Grid.of(1, 3));//内容合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 4), MergeCellRule.Grid.of(0, cellLength - 2));//验证类型合并 第一行mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, cellLength - 1), MergeCellRule.Grid.of(1, cellLength - 1));//备注合并return mergeCellRuleBuilder;}}

3. 设置表格宽度 setTableRenderDataAndColWidth

  /*** 表格赋值,* 设置列宽和合并单元格** @param rowRenderDataArray* @param cellLength* @return*/private static TableRenderData setTableRenderDataAndColWidth(RowRenderData[] rowRenderDataArray, Integer cellLength) {//table赋值set方法需要listList<RowRenderData> RowRenderDataList = Arrays.asList(rowRenderDataArray);//设置列宽:double[] colWidthsCm = new double[cellLength];for (int i = 0; i < cellLength; i++) {// "章节号", "项目", "内容" 设置为 2 ;这几列宽度大if (i == 1 || i == 2 || i == 3) {colWidthsCm[i] = 2D;} else {colWidthsCm[i] = 1D;}}//18.450000762939453D A4纸张TableRenderData check_table = Tables.ofWidth(18.450000762939453D, colWidthsCm).center().create();check_table.setRows(RowRenderDataList);//合并单元格MergeCellRule.MergeCellRuleBuilder mergeCellRuleBuilder = mergeCell(cellLength);check_table.setMergeRule(mergeCellRuleBuilder.build());return check_table;}

4. 表格合并方法 mergeCell

 /*** 表格 合并单元格** @param cellLength* @return*/private static MergeCellRule.MergeCellRuleBuilder mergeCell(Integer cellLength) {/*** 设置表格合并规则 从0开始* 1.起始行 MergeCellRule.Grid.of(i, j) i: 行 j: 列* 2.结束行 MergeCellRule.Grid.of(i, j) i: 行 j: 列*///合并单元格//合并到【备注】前一列MergeCellRule.MergeCellRuleBuilder mergeCellRuleBuilder = MergeCellRule.builder();mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 0), MergeCellRule.Grid.of(1, 0));//序号合并 上下行合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 1), MergeCellRule.Grid.of(1, 1));//章节号合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 2), MergeCellRule.Grid.of(1, 2));//项目合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 3), MergeCellRule.Grid.of(1, 3));//内容合并mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, 4), MergeCellRule.Grid.of(0, cellLength - 2));//验证类型合并 第一行mergeCellRuleBuilder.map(MergeCellRule.Grid.of(0, cellLength - 1), MergeCellRule.Grid.of(1, cellLength - 1));//备注合并return mergeCellRuleBuilder;}

自定义标题

标题可以采用原生poi生成,这里实现利用的是poi-tl的Markdown插件中的标题;
最终生成的样式如下

1. word模板内容如下

{{?comment}}
Heading1简介
Heading2简介
Heading3简介
Heading4简介
Heading5简介
{{/comment}}
{{md}}

黑色内容是word模板上的内容
## 2. md文件内容如下

3. 需要生成的标题按照md文件格式拼接为字符串即可

代码如下:

public class test {public static void main(String[] args) throws IOException {//要写入模板的数据Map<String, Object> datas = new HashMap<String, Object>();//标题的数据  需要按照md文件,标题的格式拼接数据MarkdownRenderData code = new MarkdownRenderData();
//        byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/markdown/basic1.md"));
//        String mkdn = new String(bytes);String mkdn = "### Heading 31\n" +"#### Heading 41\n" +"### Heading 32\n" +"#### Heading 42";code.setMarkdown(mkdn);MarkdownStyle style = MarkdownStyle.newStyle();style.setShowHeaderNumber(true); //设置标题序号code.setStyle(style);//标题的数据datas.put("md", code);Configure config = Configure.builder().bind("md", new MarkdownRenderPolicy()).build();XWPFTemplate.compile("src/test/resources/template_finnish/test_title.docx", config).render(datas).writeToFile("src/test/resources/out/out_markdown2.docx");}

生成标题其他注意点

1. 自己指定生成标题序号开始位置:重写DocumentVisitor.class 类

下面的内容是修改后的内容:
直接标题赋值时指定值:
或者是修改原生的getHeaderNumber() 方法

   private String getHeaderNumber(int level) {if (level == 1) return "";String str = StringUtils.join(Arrays.copyOfRange(headerNumberArray, 2, headerNumberArray.length), '.');String substring = str.substring(0, (level - 1) * 2 >= str.length() ? str.length() : (level - 1) * 2);//目前是 5.2.1.//去除标题序号的.    保持和文档上一致 类似这种5.2.1if (StringUtils.isNotEmpty(substring)) {substring = substring.substring(0, substring.length() - 1);}return substring + " ";}

2. 自动生成标题的样式,也可以按照自己想要的方式设置

方式是修改DocumentVisitor 类中的visit()方法
代码如下:展示的代码都是自己修改后的

   @Overridepublic void visit(Heading heading) {int level = heading.getLevel();resetHeaderNumberArray(level);ParagraphBuilder paraOf = Paragraphs.of().styleId(String.valueOf(level)).left().allowWordBreak();if (style.isShowHeaderNumber()) {paraOf.addText(Texts.of(getHeaderNumber(level)).style(getStyle(level)).create());}DocumentRenderData renderData = parseNode(heading);if (!renderData.getContents().isEmpty()) {ParagraphRenderData headerParagraph = (ParagraphRenderData) renderData.getContents().get(0);// paraOf.addParagraph(headerParagraph);// paraOf.addText(Texts.of("").bookmark(evalText(headerParagraph)).create());paraOf.addText(Texts.of(evalText(headerParagraph)).style(getStyle(level)).create());}of.addParagraph(paraOf.create());}/*** 自定义标题的样式;* 不使用该方法,标题样式都是标签{{md}}的样式** @param level* @return*/private Style getStyle(int level) {Style style = null;switch (level) {case 2: //标题1style = new Style("宋体", 22D); //二号字体break;case 3: //标题2style = new Style("宋体", 16D);//三号字体break;case 4: //标题3style = new Style("宋体", 14D);//四号字体break;//其他都是4号字体default:style = new Style("宋体", 14D);//二号字体break;}return style;}

上述代码中,getStyle方法用于指定自己想要修改的样式

更新目录 (wps 不支持,只支持office)

网上搜到的方式,直接采用该方法,可以生成并且更新目录

转载链接如下:
转载生成poi目录

poi-tl的方式

word模板添加标签 {{TOC}}

代码如下

public class AutoMenuWordPoi {public static void main(String[] args) throws IOException, InvalidFormatException {//要写入模板的数据Map<String, Object> datas = new HashMap<String, Object>();datas.put("TOC", "TOC");Configure config = Configure.builder().bind("TOC", new TOCRenderPolicy()).build();XWPFTemplate.compile("src/test/resources/out/out_markdownToc_poi.docx", config).render(datas).writeToFile("src/test/resources/out/out_menu1.docx");}}

也可以word已经生成目录,后面只是修改了添加标题,去更新目录

采用如下代码也可以:

public class AutoMenuWord2 {private static final String HEADING1 = "1";public static void main(String[] args) throws IOException, InvalidFormatException {XWPFDocument doc = new XWPFDocument(new FileInputStream("src/test/resources/out/out_markdown2.docx"));doc.enforceUpdateFields(); // 更新目录doc.write(new FileOutputStream("src/test/resources/out/out_markdown3.docx"));doc.close();}

}

poi-tl导出word;自定义列表序号和表格宽度,表格合并,自定义标题,更新目录相关推荐

  1. Java使用POI实现导出Word文档

    POI官网链接:http://deepoove.com/poi-tl/(方便各位博友后期深入学习) 1.首先导入POM依赖包 <dependency><groupId>com. ...

  2. poi根据模板导出word(包含图片、动态生成表格、合并单元格)(亲测有效)

    准备工作: 1.需要的jar(jar包在资源处已上传,可下载) 2.创建docx模板(doc不可以) 第一步:准备好jar(这里面的 ooxml-schemas-1.1.jar 大家可以尝试用poi- ...

  3. Java使用Poi实现导出Word段落以及表格,XWPFParagraph和XWPFRun详解,生成目录,生成折线图、柱状图、饼状图

    导出段落 public void exportSummarizeWord(HttpServletResponse response, Integer id) {Summarize summarize ...

  4. java poi 动态导出word表格带合并效果

    1.引入word导出所需依赖包 工作常用的excel,word导出,需要引入下面的6个主要包,和主要包依赖的其他包 ,可以看下面的表格进行依赖下载引入 这下面的两张图是主要包对应涉及到功能,可以按需要 ...

  5. java利用poi模板导出word文件

    注意:  doc文件的读取,需要导入poi-scratchpad包: docx文件读取,需要导入poi-ooxml包: 一.引入pom <dependency><groupId> ...

  6. POI XWPFDocument 导出word目录详解

    完整代码,代码为main方法直接运行,该代码实现了对目录样式,布局,标题,位置的修改,但是无法自动获取页码,只可以手动添加目录中对应的页码,或者设置为空.下方资源运行环境: Windows10 JDK ...

  7. java使用easypoi导出word文档,包含图片,表格,文字;

    添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:/ ...

  8. 一天实现用poi-tl导出word(饼图/柱状图、文字、表格、循环word),男朋友看完直呼好家伙

    用一天的时间实现了要求的word的导出,包含表格.饼图.文字.柱状图,男朋友直竖大拇指,非让我给他讲,学会以后直呼抱大腿,害,这无处安放的优秀. 想研究的可以自己看一下接口文档 Poi-tl Docu ...

  9. Word中公式序号的标注方法(表格法与制表位法)

    在写论文过程中难免要在文中进行公式的列举与说明,而其中最让人头疼的就是,对公式进行标准化的排序,今天我们来学习一下,word中公式排序的两种方法吧! 表格法 1.首先,创建一个一行三列的表格 2.在中 ...

最新文章

  1. Android Tab 选项卡的简单实现
  2. 伟人必须回答的(二十道问题)
  3. iOS中 HTTP/Socket/TCP/IP通信协议详解 韩俊强的博客
  4. Java怎么测并发量_如何测试一个web网站的性能(并发数)?
  5. SpringBoot @PostConstruct和@PreDestroy使用详解
  6. 原声JS面向对象实现的简单轮播
  7. node js并发加载页面缓慢_详解如何利用前端Node模块zlib开启gzip压缩使页面加载速度更快...
  8. 前端传递给后端且通过cookie方式,尽量传递id
  9. Phycharm下载并安装
  10. 类与对象(面向对象的编程语言java)
  11. 如何便捷获取参考文献的引用格式?
  12. RS-232协议和RS-485协议
  13. CSS限制字数,超出部份显示点点点...
  14. 记录archlinux第n次修复引导区
  15. 基于Open CV的植物图像分类识别项目
  16. Windows常用快捷键总结【日常总结】
  17. AutoFac基本使用-笔记
  18. 灵魂画手图解Spring循环依赖
  19. 2022年天猫618满300减30红包怎么用?
  20. 使用美图秀秀制作电子喜帖:分享幸福新方法

热门文章

  1. 微信支付出现故障,程序员的高薪理所当然
  2. 在C#中使用OpenCV(使用OpenCVSharp)
  3. sdut-3386 小雷的冰茶几
  4. 【RegNet】《Designing Network Design Spaces》
  5. 2020-03-10
  6. 如何区分m的属性_测试属性#5 –区分
  7. Java学习十四,JDBC,反射
  8. midl会议_医学图像分析相关的会议
  9. 鲁大师4月安卓新机性能/流畅榜:ROG游戏手机7摘得性能桂冠 vivo登顶流畅榜
  10. win10系统找不到telnet服务器,win10系统找不到Telnet服务的解决教程