百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Apache POI在指定位置插入表格(apache poi生成execel)

toyiye 2024-09-02 02:18 4 浏览 0 评论

接到的需求是在模板表格的指定位置再插入表格。比如在模板的${proTable}处插入表格。

依赖的包

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi</artifactId>
 <version>3.15</version>
</dependency>
<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml</artifactId>
 <version>3.15</version>
</dependency>

插入表格

由于是在表格里的指定地方插入表格,所以要遍历表格的每个单元格,查找到要插入点的占位符。

// 处理表
 public CustomXWPFDocument generateCoopApplyWord(Map<String, Object> param, String template) {
 CustomXWPFDocument doc = null;
 try {
 OPCPackage pack = POIXMLDocument.openPackage(template);
 doc = new CustomXWPFDocument(pack);
 if (param != null && param.size() > 0) { 
 //处理表格
 Iterator<XWPFTable> it = doc.getTablesIterator();
 while (it.hasNext()) {
 XWPFTable table = it.next();
 List<XWPFTableRow> rows = table.getRows();
 for (XWPFTableRow row : rows) {
 List<XWPFTableCell> cells = row.getTableCells();
 for (XWPFTableCell cell : cells) {
 List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
 insertTable("${proTable}",param, cell); // 在"${proTable}"处插入表格 
 }
 } 
 }
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 return doc;
 }


// 在key处插入表格
 private void insertTable(String key, Map<String, Object> param, XWPFTableCell cell) {
 List<XWPFParagraph> paragraphList = cell.getParagraphs();
 if (paragraphList != null && paragraphList.size() > 0) {
 for (XWPFParagraph paragraph : paragraphList) {
 List<XWPFRun> runs = paragraph.getRuns();
 for (XWPFRun run : runs) {
 String text = run.getText(0);
 if (text != null) {
 if (text.indexOf(key) >= 0) {
 insertWhereKindTable(paragraph, param, cell);
 }
 }
 }
 }
 }
 }


// 插入并设置表格的值
 private void insertWhereKindTable(XWPFParagraph paragraph, Map<String, Object> param, XWPFTableCell cell) {
 // 得到这个指定位置的游标
 XmlCursor cursor = paragraph.getCTP().newCursor();
		// 在cursor插入表格
 XWPFTable tableOne = cell.insertNewTbl(cursor);// ---这个是关键
		// 如果自动生成了一行,可以删掉
 boolean a = tableOne.removeRow(0);
		// 添加属性
 CTTblGrid grid = tableOne.getCTTbl().addNewTblGrid();
 grid.addNewGridCol().setW(BigInteger.valueOf(2000));
 grid.addNewGridCol().setW(BigInteger.valueOf(2000));
 grid.addNewGridCol().setW(BigInteger.valueOf(2000));
		// 设置边框样式
 tableBorderStyle(tableOne);
		// 这里是根据前端传过来的数据来填充表格
 List<Map<String, Object>> tableValueList = (List<Map<String, Object>>) param.get("fore_com_list");
 XWPFTableRow tableOneRowOne = tableOne.createRow();
 tableOneRowOne.setHeight(380);
 tableOneRowOne.addNewTableCell().setText("专业");
 tableOneRowOne.addNewTableCell().setText("工作量");
 tableOneRowOne.addNewTableCell().setText("协作比例");
 tableOneRowOne.addNewTableCell().setText("协作费用");
 for (int i = 0; i < tableValueList.size(); i++) {
 Map<String, Object> map = tableValueList.get(i);
 XWPFTableRow tableRow = tableOne.createRow();
 tableRow.setHeight(380);
 tableRow.getCell(0).setText((String) map.get("CoopProfessionName"));
 tableRow.getCell(1).setText(String.valueOf(map.get("CoopWorkProportion")));
 tableRow.getCell(2).setText(String.valueOf(map.get("CoopProportion")));
 tableRow.getCell(3).setText(String.valueOf(map.get("CoopPrice")));
 }
		
		// 设置单元格样式
 tableCellStyle(tableOne, 1500);
 }


由于创建的新表格没有属性,比如设置边框样式,行高列宽等。POI给出了方法去设置这些属性。POI处理文档都是解析成xml格式。这里是截取部分,比如:

<w:tbl>
 <w:tblPr>
 <w:tblStyle w:val="12"/>
 <w:tblW w:w="9418" w:type="dxa"/>
 <w:jc w:val="center"/>
 <w:tblInd w:w="0" w:type="dxa"/>
 <w:tblLayout w:type="fixed"/>
 <w:tblCellMar>
 <w:top w:w="0" w:type="dxa"/>
 <w:left w:w="108" w:type="dxa"/>
 <w:bottom w:w="0" w:type="dxa"/>
 <w:right w:w="108" w:type="dxa"/>
 </w:tblCellMar>
 </w:tblPr>
 <w:tblGrid>
 <w:gridCol w:w="2058"/>
 <w:gridCol w:w="2236"/>
 <w:gridCol w:w="1455"/>
 <w:gridCol w:w="3669"/>
 </w:tblGrid>
 <w:tr>
 <w:tblPrEx>
 <w:tblLayout w:type="fixed"/>
 <w:tblCellMar>
 <w:top w:w="0" w:type="dxa"/>
 <w:left w:w="108" w:type="dxa"/>
 <w:bottom w:w="0" w:type="dxa"/>
 <w:right w:w="108" w:type="dxa"/>
 </w:tblCellMar>
 </w:tblPrEx>
 <w:trPr>
 <w:trHeight w:val="494" w:hRule="atLeast"/>
 <w:jc w:val="center"/>
 </w:trPr>
 <w:tc>
 <w:tcPr>
 <w:tcW w:w="2058" w:type="dxa"/>
 <w:tcBorders>
 <w:top w:val="single" w:color="auto" w:sz="8" w:space="0"/>
 <w:left w:val="single" w:color="auto" w:sz="8" w:space="0"/>
 <w:bottom w:val="single" w:color="auto" w:sz="4" w:space="0"/>
 <w:right w:val="single" w:color="auto" w:sz="4" w:space="0"/>
 </w:tcBorders>
 <w:vAlign w:val="center"/>
 </w:tcPr>
 <w:p>
 <w:pPr>
 <w:widowControl/>
 <w:jc w:val="center"/>
 <w:rPr>
 <w:rFonts w:ascii="宋体" w:hAnsi="宋体" w:cs="宋体"/>
 <w:szCs w:val="21"/>
 </w:rPr>
 </w:pPr>
 <w:r>
 <w:rPr>
 <w:rFonts w:hint="eastAsia" w:ascii="宋体" w:hAnsi="宋体" w:cs="宋体"/>
 <w:szCs w:val="21"/>
 </w:rPr>
 <w:t>项目名称</w:t>
 </w:r>
 </w:p>
 </w:tc>

所以,如果要为新的表格设置属性,就要去操作这些节点,得到这个节点后就可以对其添加设置自己所需属性。其中:

  • CTTbl 就对应上面的 <w:tbl></w:tbl> ,得到表格属性
  • CTRow 就对应上面的 <w:tr></w:tr> ,得到行属性
  • CTTc 就对应上面的 <w:tc></w:tc> ,得到列属性
  • CTP 就对应上面的 <w:p></w:p> ,得到段落属性
  • CTR 就对应上面的 <w:r></w:r> ,得到run属性,操作文本
// 设置表格边框
 private void tableBorderStyle(XWPFTable table){
 //表格属性
 CTTblPr tablePr = table.getCTTbl().addNewTblPr();
 //表格宽度
 //CTTblWidth width = tablePr.addNewTblW();
 CTJc ctJc = tablePr.addNewJc();
 ctJc.setVal(STJc.Enum.forString("center"));
 //width.setW(BigInteger.valueOf(7000));
 //width.setType(STTblWidth.DXA);
 //表格颜色
 CTTblBorders borders=table.getCTTbl().getTblPr().addNewTblBorders();
 //表格内部横向表格颜色
 CTBorder hBorder=borders.addNewInsideH();
 hBorder.setVal(STBorder.Enum.forString("single"));
 hBorder.setSz(new BigInteger("1"));
 hBorder.setColor("000000");
 //表格内部纵向表格颜色
 CTBorder vBorder=borders.addNewInsideV();
 vBorder.setVal(STBorder.Enum.forString("single"));
 vBorder.setSz(new BigInteger("1"));
 vBorder.setColor("000000");
 //表格最左边一条线的样式
 CTBorder lBorder=borders.addNewLeft();
 lBorder.setVal(STBorder.Enum.forString("single"));
 lBorder.setSz(new BigInteger("1"));
 lBorder.setColor("000000");
 //表格最左边一条线的样式
 CTBorder rBorder=borders.addNewRight();
 rBorder.setVal(STBorder.Enum.forString("single"));
 rBorder.setSz(new BigInteger("1"));
 rBorder.setColor("000000");
 //表格最上边一条线(顶部)的样式
 CTBorder tBorder=borders.addNewTop();
 tBorder.setVal(STBorder.Enum.forString("single"));
 tBorder.setSz(new BigInteger("1"));
 tBorder.setColor("000000");
 //表格最下边一条线(底部)的样式
 CTBorder bBorder=borders.addNewBottom();
 bBorder.setVal(STBorder.Enum.forString("single"));
 bBorder.setSz(new BigInteger("1"));
 bBorder.setColor("000000");
 }


// 添加单元格属性
 private void tableCellStyle(XWPFTable table, int cellWidth) {
 List<XWPFTableRow> tableRows = table.getRows();
 for (int i = 0; i < tableRows.size(); i++) {
 XWPFTableRow xwpfTableRow = tableRows.get(i);
 List<XWPFTableCell> cellList = xwpfTableRow.getTableCells();
 for (XWPFTableCell tableCell : cellList) {
 CTTc ctTc = tableCell.getCTTc();
 CTTcPr ctTcPr = ctTc.addNewTcPr();
 ctTcPr.addNewTcW().setW(BigInteger.valueOf(cellWidth));
 ctTcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
 ctTcPr.addNewGridSpan().setVal(BigInteger.valueOf(1));
 // 添加单元格里的run属性
 CTP ctp = ctTc.getPList().get(0);
 CTPPr ctpPr = ctp.addNewPPr();
 ctpPr.addNewWidowControl();
 ctpPr.addNewJc().setVal(STJc.CENTER);
 CTParaRPr ctParaRPr = ctpPr.addNewRPr();
 CTFonts ctFontsp = ctParaRPr.addNewRFonts();
 ctFontsp.setAscii("宋体");
 ctFontsp.setHAnsi("宋体");
 ctFontsp.setCs("宋体");
 ctParaRPr.addNewSzCs().setVal(BigInteger.valueOf(21));
 CTR ctr = ctp.getRList().get(0);
 //CTR ctr = ctp.addNewR();
 CTRPr ctrPr = ctr.addNewRPr();
 CTFonts ctFonts = ctrPr.addNewRFonts();
 ctFonts.setHint(STHint.Enum.forString("eastAsia"));
 ctFonts.setEastAsia("宋体");
 ctFonts.setAscii("宋体");
 ctFonts.setHAnsi("宋体");
 ctFonts.setCs("宋体");
 ctrPr.addNewSzCs().setVal(BigInteger.valueOf(21)); 
 }
 }
 }

把返回的XWPFDocument写入到对应的流中。

FileOutputStream fopts = new FileOutputStream("E://andy.docx");
doc.write(fopts);

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码