| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- package platform.common.util;
- import org.apache.poi.POIXMLDocument;
- import org.apache.poi.xwpf.usermodel.*;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.URLEncoder;
- import java.util.*;
- /**
- * @author kevin
- * @since 2019/9/3 4:10 PM
- */
- public class BokeWordUtils {
- private XWPFDocument document;
- /**
- * 构造函数
- *
- * @param inputUrl
- * @param tableList
- */
- public BokeWordUtils(String inputUrl, List<String[]> tableList) {
- this(inputUrl, new HashMap<>(), tableList);
- }
- public BokeWordUtils(String inputUrl, Map<String, String> textMap, List<String[]> tableList) {
- try {
- System.out.println("===============开始读取word模版===================");
- System.out.println(Thread.currentThread().getName() + "\t 模版路径:" + inputUrl);
- document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
- //解析替换文本段落对象
- changeText(document, textMap);
- //解析替换表格对象
- changeTable(document, textMap, tableList);
- System.out.println("生成完成!");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 根据模板生成新word文档
- * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
- *
- * @param inputUrl 模板存放地址
- * @param outputUrl 新文档存放地址
- * @param textMap 需要替换的信息集合
- * @param tableList 需要插入的表格信息集合
- */
- public static boolean changWord(String inputUrl, String outputUrl,
- Map<String, String> textMap, List<String[]> tableList) {
- //模板转换默认成功
- boolean changeFlag = true;
- try {
- //获取docx解析对象
- XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
- //解析替换文本段落对象
- BokeWordUtils.changeText(document, textMap);
- //解析替换表格对象
- BokeWordUtils.changeTable(document, textMap, tableList);
- //生成新的word
- File file = new File(outputUrl);
- FileOutputStream stream = new FileOutputStream(file);
- document.write(stream);
- stream.close();
- System.out.println("成功生成!");
- } catch (IOException e) {
- e.printStackTrace();
- changeFlag = false;
- }
- return changeFlag;
- }
- /**
- * 根据模板生成新word文档
- * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
- * author:hzh
- * description:改为下载
- *
- * @param inputUrl 模板存放地址
- * @param response 新文档存放地址
- * @param textMap 需要替换的信息集合
- * @param tableList 需要插入的表格信息集合
- */
- public static boolean changWord(String inputUrl, HttpServletResponse response,
- Map<String, String> textMap, List<String[]> tableList) {
- //模板转换默认成功
- boolean changeFlag = true;
- try {
- //获取docx解析对象
- XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
- //解析替换文本段落对象
- BokeWordUtils.changeText(document, textMap);
- //解析替换表格对象
- BokeWordUtils.changeTable(document, textMap, tableList);
- //生成新的word
- OutputStream os = response.getOutputStream();
- document.write(os);
- os.close();
- System.out.println("成功生成!");
- } catch (IOException e) {
- e.printStackTrace();
- changeFlag = false;
- }
- return changeFlag;
- }
- /**
- * 输出到客户端
- *
- * @param fileName 输出文件名
- */
- public BokeWordUtils write(HttpServletResponse response, String fileName) throws IOException {
- response.reset();
- response.setContentType("application/octet-stream; charset=utf-8");
- response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
- write(response.getOutputStream());
- return this;
- }
- /**
- * 输出数据流
- *
- * @param os 输出数据流
- */
- public BokeWordUtils write(OutputStream os) throws IOException {
- document.write(os);
- return this;
- }
- /**
- * 替换段落文本
- *
- * @param document docx解析对象
- * @param textMap 需要替换的信息集合
- */
- public static void changeText(XWPFDocument document, Map<String, String> textMap) {
- //获取段落集合
- List<XWPFParagraph> paragraphs = document.getParagraphs();
- for (XWPFParagraph paragraph : paragraphs) {
- //判断此段落时候需要进行替换
- String text = paragraph.getText();
- if (checkText(text)) {
- List<XWPFRun> runs = paragraph.getRuns();
- for (XWPFRun run : runs) {
- //替换模板原来位置
- // run.setText(changeValue(run.toString(), textMap),0);
- String textValue = changeValue(run.toString(), textMap);
- run.setText(textValue, 0);
- }
- }
- }
- }
- /**
- * 替换表格对象方法
- *
- * @param document docx解析对象
- * @param textMap 需要替换的信息集合
- * @param tableList 需要插入的表格信息集合
- */
- public static void changeTable(XWPFDocument document, Map<String, String> textMap,
- List<String[]> tableList) {
- //获取表格对象集合
- List<XWPFTable> tables = document.getTables();
- for (int i = 0; i < tables.size(); i++) {
- //只处理行数大于等于2的表格,且不循环表头
- XWPFTable table = tables.get(i);
- //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
- if (checkText(table.getText())) {
- List<XWPFTableRow> rows = table.getRows();
- //遍历表格,并替换模板
- eachTable(rows, textMap);
- } else {
- insertTable(table, tableList);
- }
- }
- }
- /**
- * 遍历表格
- *
- * @param rows 表格行对象
- * @param textMap 需要替换的信息集合
- */
- public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
- for (XWPFTableRow row : rows) {
- List<XWPFTableCell> cells = row.getTableCells();
- for (XWPFTableCell cell : cells) {
- //判断单元格是否需要替换
- if (checkText(cell.getText())) {
- List<XWPFParagraph> paragraphs = cell.getParagraphs();
- for (XWPFParagraph paragraph : paragraphs) {
- List<XWPFRun> runs = paragraph.getRuns();
- for (XWPFRun run : runs) {
- run.setText(changeValue(run.toString(), textMap), 0);
- }
- }
- }
- }
- }
- }
- /**
- * 为表格插入数据,行数不够添加新行
- *
- * @param table 需要插入数据的表格
- * @param tableList 插入数据集合
- */
- public static void insertTable(XWPFTable table, List<String[]> tableList) {
- //创建行,根据需要插入的数据添加新行,不处理表头
- for (int i = 0; i < tableList.size(); i++) {
- XWPFTableRow row = table.createRow();
- List<XWPFTableCell> cells = row.getTableCells();
- for (int j = 0; j < cells.size(); j++) {
- XWPFTableCell cell = cells.get(j);
- cell.setText(tableList.get(i)[j]);
- }
- }
- //遍历表格插入数据
- // List<XWPFTableRow> rows = table.getRows();
- // for(int i = 1; i < rows.size(); i++){
- // XWPFTableRow newRow = table.getRow(i);
- // List<XWPFTableCell> cells = newRow.getTableCells();
- // for(int j = 0; j < cells.size(); j++){
- // XWPFTableCell cell = cells.get(j);
- // cell.setText(tableList.get(i-1)[j]);
- // }
- // }
- }
- /**
- * 判断文本中时候包含$
- *
- * @param text 文本
- * @return 包含返回true, 不包含返回false
- */
- public static boolean checkText(String text) {
- boolean check = false;
- if (text.indexOf("$") != -1) {
- check = true;
- }
- return check;
- }
- /**
- * 匹配传入信息集合与模板
- *
- * @param value 模板需要替换的区域
- * @param textMap 传入信息集合
- * @return 模板需要替换区域信息集合对应值
- */
- public static String changeValue(String value, Map<String, String> textMap) {
- Set<Map.Entry<String, String>> textSets = textMap.entrySet();
- for (Map.Entry<String, String> textSet : textSets) {
- //匹配模板与替换值 格式${key}
- String key = "${" + textSet.getKey() + "}";
- if (value.indexOf(key) != -1) {
- // value = textSet.getValue();//全部参数替换
- if (value != null && textSet != null && textSet.getValue() != null) {
- try {
- value = value.replace(key, textSet.getValue());//仅替换参数
- }catch (Exception e){
- System.out.println(e.getMessage());
- }
- }
- }
- }
- //模板未匹配到区域替换为空
- if (checkText(value)) {
- value = "";
- }
- return value;
- }
- public static void main(String[] args) {
- //模板文件地址
- String inputUrl = "/.docx";
- //新生产的模板文件
- String outputUrl = "/.docx";
- Map<String, String> testMap = new HashMap<String, String>();
- testMap.put("name", "小明");
- testMap.put("sex", "男");
- testMap.put("age", "18");
- testMap.put("address", "北京市");
- testMap.put("neirong", "好的内容");
- testMap.put("xuehao", "88888888");
- testMap.put("companyName", "软通");
- testMap.put("bigName", "项目大类");
- testMap.put("smileName", "项目大类-小类");
- testMap.put("phone", "18388888888");
- testMap.put("date", DateUtil.getTimeString(new Date()));
- List<String[]> tableList = new ArrayList<>();
- tableList.add(new String[]{"1", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"2", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"3", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"4", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"5", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"6", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- tableList.add(new String[]{"7", "1mm", "1开开", "1uu", "5", "6", "7", "8", "9"});
- // tableList.add(new String[]{"2","2密码","2B","基金C"});
- // tableList.add(new String[]{"3","3看看","3B","基看C"});
- // tableList.add(new String[]{"4","4累了","4B","4谁说的"});
- BokeWordUtils.changWord(inputUrl, outputUrl, testMap, tableList);
- }
- }
|