POI和POI-TL操作Word

news/2024/11/19 13:30:05/

POI操作Word

操作依赖包org.apache.poi,包括poi和poi-ooxml。

创建空白Word文件

    void poiCreateNewWord() {String path = "C:\\Users\\wisdom21111\\Desktop\\";XWPFDocument document = new XWPFDocument();try {FileOutputStream out = new FileOutputStream(path + "newFile.docx");document.write(out);out.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

复制Word文件

    void poiCopyFile() throws IOException {XWPFDocument xwpfDocument1 = new XWPFDocument(new FileInputStream("C:\\Users\\wisdom21111\\Desktop\\oldFile.docx"));XWPFDocument xwpfDocument2 = xwpfDocument1;FileOutputStream out = new FileOutputStream("C:\\Users\\wisdom21111\\Desktop\\newFile.docx");xwpfDocument2.write(out);out.close();}

合并Word文档

    @Testvoid poiMergeMultiFile(File[] files,String outfile) throws IOException, XmlException {XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream(files[0]));CTBody ctBody = xwpfDocument.getDocument().getBody();String srcstr = ctBody.xmlText(); //<xml-fragment ...>...</xml-frament> 整体信息String prefix = srcstr.substring(0,srcstr.indexOf(">")+1); //<xml-frament ...> 头String suffix = srcstr.substring(srcstr.lastIndexOf("<")); //</xml-frament> 尾String mainbody = srcstr.substring(srcstr.indexOf(">")+1,srcstr.lastIndexOf("<")); //...主体内容List<String> list = new ArrayList<>();//使用循环遍历获得后续文件内容for(int i=1;i<files.length;i++){XWPFDocument xwpfDocument1 = new XWPFDocument(new FileInputStream(files[i]));CTBody ctBody1 = xwpfDocument1.getDocument().getBody();String appendContent = ctBody1.xmlText().substring(srcstr.indexOf(">")+1,srcstr.lastIndexOf("<")); //后续文件的主体内容list.add(appendContent);}StringBuilder sb = new StringBuilder();sb.append(prefix); //xml头sb.append(mainbody); //第一个文件主体内容for(String str:list){sb.append("    <w:p>\n" +"        <w:pPr>\n" +"            <w:pageBreakBefore w:val=\"true\"/>\n" +"        </w:pPr>\n" +"    </w:p>"); // 分页符sb.append(str); //后续文件主体}sb.append(suffix); //xml文件尾CTBody ctResult = CTBody.Factory.parse(sb.toString());ctBody.set(ctResult); //重新设置第一个文件内容FileOutputStream outputStream = new FileOutputStream(outfile);xwpfDocument.write(outputStream);outputStream.flush();xwpfDocument.close();outputStream.close();}@Testvoid poiMergeMultiFileTest() throws IOException, XmlException {File one = new File("C:\\Users\\wisdom21111\\Desktop\\File.docx");File two = new File("C:\\Users\\wisdom21111\\Desktop\\File.docx");File three = new File("C:\\Users\\wisdom21111\\Desktop\\File.docx");String out = "C:\\Users\\wisdom21111\\Desktop\\new.docx";File[] files = new File[]{one,two,three};poiMergeMultiFile(files,out);}

合并Word文档简洁方法,使用POI-TL

    //依赖包 com.deepoove.poivoid nicePoiMergeFile() throws Exception {NiceXWPFDocument niceXWPFDocument1 = new NiceXWPFDocument(ne FileInputStream("C:\\Users\\wisdom21111\\Desktop\\output.docx"));NiceXWPFDocument niceXWPFDocument2 = new NiceXWPFDocument(ne FileInputStream("C:\\Users\\wisdom21111\\Desktop\\output.docx"));niceXWPFDocument1.createParagraph().setPageBreak(true);NiceXWPFDocument newDoc = niceXWPFDocument1.merge(niceXWPFDocument2);FileOutputStream out = new FileOutputStream("C:\\Users\\wisdom21111\\Desktop\\new_doc.docx");newDoc.write(out);newDoc.close();out.close();}

使用POI-TL根据模板生成Word文件

    HashMap<String,Object> hashMap = new HashMap<>();hashMap.put("str","我是字符串");XWPFTemplate template = XWPFTemplate.compile("C:\\Users\\wisdom21111\\Desktop\\template.docx").render(hashMap);template.writeAndClose(new FileOutputStream("C:\\Users\\wisdom21111\\Desktop\\output.docx"));
文本标签 {{str}}
图片标签 {{@image}}
表格标签 {{#table}}
    hashMap.put("str","Hello,World");hasnMap.put("image","C:\\Users\\wisdom21111\\Desktop\\xxx.jpeg");//创建表格第一种方式hashMap.put("table",Tables.of(new String[][]{new String[][]{"00","01"},new String[][]{"10","11"}}).border(BorderStyle.DEFAULT).create());//创建表格第二种方式RowRenderData row0 = Rows.of("姓名","性别").textColor("FFFFFF").bgColor("4472C4").center().create();RowRenderData row1 = Rows.create("张三","男");hashMap.put("table",Tables.create(row0,row1));
引用标签替换图片,编辑替换文字-替换文字 {{img}}
    put("img",Pictures.ofLocal("C:\\Users\\wisdom21111\\Desktop\\newPic.jpg").create());

POI-TL表格行循环

    void poitlRowTest() throws IOException {Student student1 = new Student("张三","男","一班","001");Student student2 = new Student("李四","男","一班","002");Student student3 = new Student("王五","男","一班","003");List<Student> list = asList(student1,student2,student3);LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();Configure config = Configure.builder().bind("list",policy).build();HashMap<String,Object> hashMap = new HashMap<>();hashMap.put("list",list);XWPFTemplate template = XWPFTemplate.compile("C:\\Users\\wisdom21111\\Desktop\\template.docx",config).render(hashMap);template.writeAndClose(new FileOutputStream("C:\\Users\\wisdom21111\\Desktop\\hello.docx"));}
模板template.docx

在这里插入图片描述


POI-TL创建表格

void poitlCreateTable() throws IOException {//表格行,注意每行的单元格数量相同RowRenderData row0 =Rows.of("功率因数","允许误差","电流","实际相对误差",null,null).center().crate();RowRenderData row1 =Rows.of(null,null,null,"{{bar1}}","{{bar2}}","{{bar3}}").center().create();RowRenderData row2 =Rows.of("{{name}}","{{f1}}","{{a1}}","{{r11}}","{{r12}}","{{r13}}").center.create();RowRenderData row3 =Rows.of(null,null,"{{a2}}","{{r21}}","{{r22}}","{{r23}}").center().create(;RowRenderData row4 =Rows.of(null,null,"{{a3}}","{{r31}}","{{r32}}","{{r33}}").center().create(;RowRenderData row5 =Rows.of(null,null,"{{a4}}","{{r41}}","{{r42}}","{{r43}}").center().create(;RowRenderData row6 =Rows.of(null,null,"{{a5}}","{{r51}}","{{r52}}","{{r53}}").center().create(;RowRenderData row7 =Rows.of(null,"{{f2}}","{{a6}}","{{r61}}","{{r62}}","{{r63}}").center().crete();//单元格合并规格Map<MergeCellRule.Grid, MergeCellRule.Grid> map = new HashMap<>();map.put(MergeCellRule.Grid.of(0,0), MergeCellRule.Grid.of(1,0));map.put(MergeCellRule.Grid.of(0,3), MergeCellRule.Grid.of(0,5));map.put(MergeCellRule.Grid.of(0,1), MergeCellRule.Grid.of(1,1));map.put(MergeCellRule.Grid.of(0,2), MergeCellRule.Grid.of(1,2));map.put(MergeCellRule.Grid.of(2,0), MergeCellRule.Grid.of(7,0));map.put(MergeCellRule.Grid.of(2,1), MergeCellRule.Grid.of(6,1));MergeCellRule.MergeCellRuleBuilder mergeCellRuleBuilder =MergeCellRule.builder();for(Map.Entry<MergeCellRule.Grid, MergeCellRule.Grid> e:map.entrySet()){mergeCellRuleBuilder.map(e.getKey(),e.getValue());}//将表格添加到模板中Map<String,Object> hashMap = new HashMap<>();hashMap.put("table",Tables.of(row0,row1,row2,row3,row4,row5,row6,row7).mereRule(mergeCellRuleBuilder.build()).create());XWPFTemplate template =XWPFTemplate.compile("C:\\Users\\wisdom21111\\Desktop\\template.docx").rener(hashMap);template.writeAndClose(newFileOutputStream("C:\\Users\\wisdom21111\\Desktop\\hello.docx"));
}
创建效果:

在这里插入图片描述


POI动态表格

创建表格数据类
public class DetailData {private List<RowRenderData> goods;private List<RowRenderData> labors;//...省略get/set方法
}
创建自定义渲染类
    public class DetailTablePolicy extends DynamicTableRenderPolicy {//表格渲染策略int goodStartRow = 2;int laborStartRow = 5;@Overridepublic void render(XWPFTable xwpfTable, Object o) throws Exception {if(null==o){return;}DetailData detailData = (DetailData)o;List<RowRenderData> labors = detailData.getLabors();if(null!=labors){xwpfTable.removeRow(laborStartRow);//循环插入for(int i=0;i<labors.size();i++){XWPFTableRow insertRow = xwpfTable.insertNewTableRow(laborStartRow);for(int j=0;j<7;j++) insertRow.createCell();TableTools.mergeCellsHorizonal(xwpfTable,laborStartRow,0,3);TableRenderPolicy.Helper.renderRow(xwpfTable.getRow(laborStartRow),labors.get(i));}}List<RowRenderData> goods = detailData.getGoods();if (null != goods) {xwpfTable.removeRow(goodStartRow);for (int i = 0; i < goods.size(); i++) {XWPFTableRow insertNewTableRow = xwpfTable.insertNewTableRow(goodStartRow);for (int j = 0; j < 7; j++) insertNewTableRow.createCell();TableRenderPolicy.Helper.renderRow(xwpfTable.getRow(goodStartRow), goods.get(i));}}}
}
填充数据执行渲染
void dynamicRenderTable() throws IOException {//动态表格 从底部向上逐个添加//自上向下添加位置不易确定DetailData detailData = new DetailData();RowRenderData good =Rows.of("4","墙纸","书房+卧室","1500","/","400","1600").center().create();List<RowRenderData> goodList = Arrays.asList(good,good,good);RowRenderData labor = Rows.of("油漆工","2","200","400").center().create();List<RowRenderData> laborList = Arrays.asList(labor,labor,labor,labor);detailData.setGoods(goodList);detailData.setLabors(laborList);Map<String,Object> map = new HashMap<>();map.put("detail_table",detailData);Configure config = Configure.builder().bind("detail_table",newDetailTablePolicy()).build();XWPFTemplate template =XWPFTemplate.compile("C:\\Users\\wisdom21111\\Desktop\\template.docx",confg).render(map);template.writeToFile("C:\\Users\\wisdom21111\\Desktop\\hello2.docx");
}
模板预览:

在这里插入图片描述

生成预览:

在这里插入图片描述


http://www.ppmy.cn/news/911917.html

相关文章

beagleboneblack(BBB)开发板使用NFS挂载根文件系统,tftp下载镜像与设备树

一、文件下载 交叉编译工具链下载地址 wget -c https://releases.linaro.org/components/toolchain/binaries/6.5-2018.12/arm-linux-gnueabihf/gcc-linaro-6.5.0-2018.12-i686_arm-linux-gnueabihf.tar.xz beagleboneblack内核kernel下载地址&#xff0c;切换到tag为4.19.94-t…

数据结构与算法基础ppt

根据数据结构C语言版第2版书编写。想要电子书的童鞋可以私我 B站学习地址 9.13开始 9.29更新到p118 线性表 2.1线性表的定义和特点 P10 2.2 案例引入 p11 2.3 线性表的类型定义 p12 2.4 线性表的顺序表示和实现1 p13 2.4 线性表的顺序表示和实现2 p14 P15 第02周06–类C语言…

ia笔记总结

HCIA 计算机 使用二进制语言 应用层&#xff1a;人机交互的接口&#xff0c;自然语言转化为编码表示层&#xff1a;编码–>二进制&#xff0c;翻译介质访问控制层&#xff1a;控制硬件物理层:CPU 对等网 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接…

golang打包后在另一台电脑运行报错/lib64/libc.so.6: version `GLIBC_xxxx‘ not found解决方案

前言 最近使用golang打包项目出现个问题报错/lib64/libc.so.6: version GLIBC_xxxx’ not found&#xff0c;很多人都说需要安装GLIBC解决&#xff0c;但是这里有个误区&#xff0c;好像CGO库是依赖glibc的&#xff08;具体的我也没有考证&#xff09;就是我根部就没有使用CGO…

jakarta ee_Jakarta EE社区之声:Jakarta EE的未来是什么?

jakarta ee 本月初&#xff0c;Jakarta EE社区成员被邀请参加Jakarta EE社区之声文档 &#xff0c;该文档重点关注Jakarta EE规范的技术创新。 本文档中的内容反映了参与者对他们希望贡献时间的领域的个人观点。 但是&#xff0c;必须提及的是&#xff0c;它们并不代表硬性承诺…

C#正则表达式通过HTML提取网页中的图片src

C#正则表达式通过HTML提取网页中的图片src 原文: C#正则表达式通过HTML提取网页中的图片src 目前在做HoverTreeCMS项目中有处理图片的部分&#xff0c;参考了一下网上案例&#xff0c;自己写了一个获取内容中的图片地址的方法。可以先看看效果&#xff1a;http://tool.hovertre…

leetcode|math|9.172.69.50.

9. Palindrome Number to_string 就行 172. Factorial Trailing Zeroes 不能直接乘起来&#xff0c;会overflow&#xff01;&#xff01; 166! 就是要找166乘到1一共有几个5。5&#xff0c;10&#xff0c;15&#xff0c;25...都算。166/5就是算一共有几个5。但是25其实贡献了…

2023-07-16 LeetCode每日一题(树中距离之和)

2023-07-16每日一题 一、题目编号 834. 树中距离之和二、题目链接 点击跳转到题目位置 三、题目描述 给定一个无向、连通的树。树中有 n 个标记为 0…n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges &#xff0c; edges[i] [ai, bi]表示树中的节点 ai 和 bi 之间有…