/**
* @Title: WordTemplate2.java
* @Package: com.highdata.templateTools
* @Description: TODO
* @author: Juveniless
* @date: 2017年11月27日 下午3:23:13
*/
package com.hidata.tool;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.stream.FileImageInputStream;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
/**
*
* 对docx文件中的文本及表格中的内容进行替换 --模板仅支持对 {key} 标签的替换
*
* @ClassName: WordTemplate
* @Description: TODO(!!!使用word2013 docx文件)
* @author Juveniless
* @date: 2017年11月27日 下午3:25:56
* <br>(1)word模板注意页边距的问题,存在问题:比如页边距默认为3cm,画表格时,仍然可以通过
* 拖拽,把表格边框拖动到看起来就像页边距只有1cm的样子,但是实际上此时页边距还是3cm,生成的
* word报表的页边距还是会按照3cm来生成。解决办法,在word文件里,设置好页边距,如果需要表格
* 两边页边距很窄,需要在word里设置页边距窄一点,而不是直接拖动表格边框来实现。
*
*/
public class WordTemplate {
private XWPFDocument document;
public XWPFDocument getDocument() {
return document;
}
public void setDocument(XWPFDocument document) {
this.document = document;
}
/**
* 初始化模板内容
*
* @author Juveniless
* @date 2017年11月27日 下午3:59:22
* @param inputStream
* 模板的读取流(docx文件)
* @throws IOException
*
*/
public WordTemplate(InputStream inputStream) throws IOException {
document = new XWPFDocument(inputStream);
}
/**
* 将处理后的内容写入到输出流中
*
* @param outputStream
* @throws IOException
*/
public void write(OutputStream outputStream) throws IOException {
document.write(outputStream);
}
/**
* 根据dataMap对word文件中的标签进行替换; <br><br>
* !!!!***需要注意dataMap的数据格式***!!!! <br><br>
* 对于需要替换的普通标签数据标签(不需要循环)-----必须在dataMap中存储一个key为parametersMap的map,
* 来存储这些不需要循环生成的数据,比如:表头信息,日期,制表人等。 <br><br>
* 对于需要循环生成的表格数据------key自定义,value为 --ArrayList<Map<String, String>>
* @author Juveniless
* @date 2017年11月27日 下午3:29:27
* @param dataMap
*
*/
public void replaceDocument(Map<String, Object> dataMap) {
if (!dataMap.containsKey("parametersMap")) {
System.out.println("数据源错误--数据源(parametersMap)缺失");
return;
}
@SuppressWarnings("unchecked")
Map<String, Object> parametersMap = (Map<String, Object>) dataMap
.get("parametersMap");
List<Map<String, Object>> tableList = (List<Map<String, Object>>) dataMap
.get("tableList");
List<IBodyElement> bodyElements = document.getBodyElements();// 所有对象(段落+表格)
int templateBodySize = bodyElements.size();// 标记模板文件(段落+表格)总个数
int curT = 0;// 当前操作表格对象的索引
int curP = 0;// 当前操作段落对象的索引
for (int a = 0; a < templateBodySize; a++) {
IBodyElement body = bodyElements.get(a);
if (BodyElementType.TABLE.equals(body.getElementType())) {// 处理表格
XWPFTable table = body.getBody().getTableArray(curT);
List<XWPFTable> tables = body.getBody().getTables();
table = tables.get(curT);
if (table != null) {
// 处理表格
List<XWPFTableCell> tableCells = table.getRows().get(0).getTableCells();// 获取到模板表格第一行,用来判断表格类型
String tableText = table.getText();// 表格中的所有文本
if (tableText.indexOf("##{foreach") > -1) {
// 查找到##{foreach标签,该表格需要处理循环
if (tableCells.size() != 2
|| tableCells.get(0).getText().indexOf("##{foreach") < 0
|| tableCells.get(0).getText().trim().length() == 0) {
System.out
.println("文档中第"
+ (curT + 1)
+ "个表格模板错误,模板表格第一行需要设置2个单元格,"
+ "第一个单元格存储表格类型(##{foreachTable}## 或者 ##{foreachTableRow}##),第二个单元格定义数据源。");
return;
}
String tableType = tableCells.get(0).getText();
String dataSource = tableCells.get(1).getText();
System.out.println("读取到数据源:"+dataSource);
if (!dataMap.containsKey(dataSource)) {
System.out.println("文档中第" + (curT + 1) + "个表格模板数据源缺失");
return;
}
@SuppressWarnings("unchecked")
List<Map<String, Object>> tableDataList = (List<Map<String, Object>>) dataMap
.get(dataSource);
if ("##{foreachTable}##".equals(tableType)) {
// System.out.println("循环生成表格");
addTableInDocFooter(table, tableDataList, parametersMap, 1);
} else if ("##{foreachTableRow}##".equals(tableType)) {
// System.out.println("循环生成表格内部的行");
addTableInDocFooter(table, tableDataList, parametersMap, 2);
}
} else if (tableText.indexOf("{") > -1) {
// 没有查找到##{foreach标签,查找到了普通替换数据的{}标签,该表格只需要简单替换
addTableInDocFooter(table, tableList, parametersMap, 1);
} else {
// 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。
addTableInDocFooter(table, null, null, 0);
}
curT++;
}
} else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 处理段落
// System.out.println("获取到段落");
XWPFParagraph ph = body.getBody().getParagraphArray(curP);
if (ph != null) {
// htmlText = htmlText+readParagraphX(ph);
addParagraphInDocFooter(ph, null, parametersMap, 0);
curP++;
}
}
}
// 处理完毕模板,删除文本中的模板内容
for (int a = 0; a < templateBodySize; a++) {
document.removeBodyElement(0);
}
}
/**
* 根据 模板表格 和 数据list 在word文档末尾生成表格
* @author Juveniless
* @date 2017年12月6日 上午10:12:05
* @param templateTable 模板表格
* @param list 循环数据集
* @param parametersMap 不循环数据集
* @param flag (0为静态表格,1为表格整体循环,2为表格内部行循环,3为表格不循环仅简单替换标签即可)
*
*/
public void addTableInDocFooter(XWPFTable templateTable, List<Map<String, Object>> list,
Map<String, Object> parametersMap, int flag) {
if (flag == 1) {// 表格整体循环
for (Map<String, Object> map : list) {
List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
for (int i = 0; i < templateTableRows.size(); i++) {
XWP
基于poi导出word以及图片
1星 需积分: 23 40 浏览量
2019-05-13
17:22:58
上传
评论
收藏 141KB ZIP 举报
逃离互联网
- 粉丝: 3
- 资源: 5
最新资源
- Screenshot_20240427_031602.jpg
- 网页PDF_2024年04月26日 23-46-14_QQ浏览器网页保存_QQ浏览器转格式(6).docx
- 直接插入排序,冒泡排序,直接选择排序.zip
- 在排序2的基础上,再次对快排进行优化,其次增加快排非递归,归并排序,归并排序非递归版.zip
- 实现了7种排序算法.三种复杂度排序.三种nlogn复杂度排序(堆排序,归并排序,快速排序)一种线性复杂度的排序.zip
- 冒泡排序 直接选择排序 直接插入排序 随机快速排序 归并排序 堆排序.zip
- 课设-内部排序算法比较 包括冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、归并排序和堆排序.zip
- Python排序算法.zip
- C语言实现直接插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序、归并排序、计数排序,并带图详解.zip
- 常用工具集参考用于图像等数据处理
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈