找网站开发人员程序员开发软件被拿去违法
本文主要功能是解析word模板
这是一个word解析类,因为我做的系统用到了而且没有可用的帮助类,只能自己写。之前的实现方式是freemarker 模板解析。但是这次要求用poi不在使用freemarker。实现功能比较少,主要是满足开发需求即可,没有实现其它功能。实现功能如下:
1、word内文本内容解析
2、word内表格内容解析
3、word内图片内容解析
4、word脚注内容解析
功能实现的比较匆忙没有好好设计,如果可以将图标,图片,脚注等设置为实体类,便于配置管理。
import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.util.Base64;
 import java.util.List;
 import java.util.Properties;
import org.apache.poi.util.Units;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
 import org.apache.poi.xwpf.usermodel.XWPFFootnote;
 import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.apache.poi.xwpf.usermodel.XWPFPicture;
 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;
 import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
 import org.springframework.util.PropertyPlaceholderHelper;
import com.alibaba.cloud.commons.lang.StringUtils;
/**
  * 通过word模板生成新的word工具类
  **
  */
 public class WordUtil {
     public static final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
    /**
      * 根据模板生成新word文档 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
      * 
      * @param textMap 需要替换的信息集合
      * @return 成功返回true,失败返回false
      */
     public static void changWord(InputStream inputStream, Properties properties, int height, int width) {
        // InputStream in = null;
         try {
             // 获取docx解析对象
             XWPFDocument document = new XWPFDocument(inputStream);
             // 解析替换文本段落对象
             WordUtil.changeText(document, properties);
             // 解析替换表格对象
             WordUtil.changeTable(document, properties);
             // 替换文本中的图片
             WordUtil.changePicture(document, properties, height, width);
             // 脚注/尾注解析 footnote
             WordUtil.changeFootNote(document, properties);
            File file = new File("I://实体文件.docx");
             FileOutputStream stream = new FileOutputStream(file);
             document.write(stream);
             stream.close();
             document.close();
        } catch (Exception e) {
             e.printStackTrace();
         }
     }
    /**
      * 尾注解析
      * 
      * @param document
      * @param properties
      */
     public static void changeFootNote(XWPFDocument document, Properties properties) {
         List<XWPFFootnote> footNoteList = document.getFootnotes();
         for (XWPFFootnote footnote : footNoteList) {
             List<XWPFParagraph> paragraphs = footnote.getParagraphs();
             for (XWPFParagraph paragraph : paragraphs) {
                 String text = paragraph.getText();
                 if (checkText(text)) {
                     List<XWPFRun> runs = paragraph.getRuns();
                     String key = keyParam(runs);
                     for (XWPFRun run : runs) {
                         run.setText("", 0);
                     }
                     // 替换模板原来位置
                     String value = changeValue(key, properties);
                     // 字符串中有可能是图片转换的字符串
                     if (StringUtils.isNotEmpty(value)) {
                         runs.get(0).setText(value, 0);
                     }
                }
             }
         }
     }
    /***
      * 指定替换模板中的图片
      * 
      * @param document
      * @param filePath
      * @param height
      * @param width
      */
     public static void changePicture(XWPFDocument document, Properties properties, Integer height, Integer width) {
        // 获取段落集合
         List<XWPFParagraph> paragraphs = document.getParagraphs();
         for (XWPFParagraph paragraph : paragraphs) {
             // 判断此段落时候需要进行替换
             String text = paragraph.getText();
             if (checkText(text)) {
                 List<XWPFRun> runs = paragraph.getRuns();
                 String key = keyParam(runs);
                 for (XWPFRun run : runs) {
                     // 字符串中有可能是图片转换的字符串
                     String value = changeValue(key, properties);
                     if (value.startsWith("data:image")) {
                         byte[] imageBytes = Base64.getDecoder().decode(value.split(",")[1]); // 获取Base64编码后的图像数据部分
                        try(ByteArrayInputStream in = new ByteArrayInputStream(imageBytes); ){// 创建ByteArrayInputStream对象
                         // 添加图片
                         XWPFPicture xwpfPicture = run.addPicture(in, XWPFDocument.PICTURE_TYPE_JPEG, "图片1.jpg",
                                 Units.toEMU(width), Units.toEMU(height));
                         // 为图片添加边框
                         xwpfPicture.getCTPicture().getSpPr().addNewLn().addNewSolidFill().addNewSchemeClr()
                                 .setVal(STSchemeColorVal.Enum.forString("tx1"));
                         }catch(Exception e) {
                             e.printStackTrace();
                         }
                     }
                 }
             }
         }
     }
    public static String keyParam(List<XWPFRun> runs) {
         if (runs.isEmpty()) {
             return "";
         }
         StringBuffer st = new StringBuffer();
         // 转换为一个字符串 [${E_002, 1, }${E_002, 2, }${E_002, 3, }]
         for (XWPFRun run : runs) {
             st.append(run.text());
         }
         return st.toString().replace(",", "");
     }
    /**
      * 替换段落文本
      * 
      * @param document docx解析对象
      * @param textMap  需要替换的信息集合
      */
     public static void changeText(XWPFDocument document, Properties properties) {
         // 获取段落集合
         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) {
                     // 替换模板原来位置
                     String value = changeValue(run.toString(), properties);
                     // 字符串中有可能是图片转换的字符串
                     if (StringUtils.isNotEmpty(value) && !value.startsWith("data:image")) {
                         run.setText(value, 0);
                     }
                 }
             }
         }
}
    /**
      * 替换表格对象方法
      * 
      * @param document docx解析对象
      * @param textMap  需要替换的信息集合
      */
     public static void changeTable(XWPFDocument document, Properties properties) {
         // 获取表格对象集合
         List<XWPFTable> tables = document.getTables();
         for (int i = 0; i < tables.size(); i++) {
             // 只处理行数大于等于2的表格,且不循环表头
             XWPFTable table = tables.get(i);
             if (table.getRows().size() > 1) {
                 // 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                 if (checkText(table.getText())) {
                     List<XWPFTableRow> rows = table.getRows();
                     // 遍历表格,并替换模板
                     eachTable(rows, properties);
                 }
             }
         }
     }
    /**
      * 遍历表格
      * 
      * @param rows    表格行对象
      * @param textMap 需要替换的信息集合
      */
     public static void eachTable(List<XWPFTableRow> rows, Properties properties) {
         for (XWPFTableRow row : rows) {
             List<XWPFTableCell> cells = row.getTableCells();
             for (XWPFTableCell cell : cells) {
                 // 判断单元格是否需要替换
                 if (checkText(cell.getText())) {
                     // 基本一个单元格,都是size=1,如果预防意外,可以增加判断,或者添加循环
                     List<XWPFParagraph> paragraphs = cell.getParagraphs();
                     // System.out.println(String.format("text:%s,paragraphs:%d",cell.getText(),
                     // paragraphs.size()));
                     // for (XWPFParagraph paragraph : paragraphs) {
                     // List<XWPFRun> runs = paragraph.getRuns();
                     // 替换模板原来位置
                     XWPRunValue(paragraphs.get(0).getRuns(), properties);
                     // }
                 }
             }
         }
     }
    /**
      * 这个方法是一次处理一个单元格,一个单元格内,被解析成了 XWPFRun, 只给第一个 XWPFRun赋值即可,其它都赋值""
      * 
      * @param runs
      * @param textMap
      */
     public static void XWPRunValue(List<XWPFRun> runs, Properties properties) {
         if (runs.size() == 1) {
             runs.get(0).setText(changeValue(runs.get(0).toString(), properties), 0);
             return;
         }
         StringBuffer st = new StringBuffer();
         // 转换为一个字符串 [${E_002, 1, }${E_002, 2, }${E_002, 3, }]
         for (XWPFRun run : runs) {
             //
             st.append(run.text());
             run.setText("", 0);
         }
         String value = st.toString().replace(",", "");
         value = changeValue(value, properties);
         // 一次性替换全部的值
         runs.get(0).setText(value, 0);
     }
    /**
      * 判断文本中时候包含$
      * 
      * @param text 文本
      * @return 包含返回true,不包含返回false
      */
     public static boolean checkText(String text) {
         return (text.indexOf("$") != -1);
     }
    /**
      * 匹配传入信息集合与模板
      * 
      * @param value   模板需要替换的区域
      * @param textMap 传入信息集合
      * @return 模板需要替换区域信息集合对应值
      */
     public static String changeValue(String value, Properties properties) {
         if (!checkText(value)) {
             return value;
         }
         return helper.replacePlaceholders(value, properties);
     }
     public static void main(String[] args) throws Exception {
         // 从FTP读取文件模板
         InputStream is = new FileInputStream(new File("I://模板文件.docx"));
        // 填充文本和表格需要替换的数据
         Properties properties = new Properties();
         properties.put("E_0001", "2000年01月01日");
         properties.put("E_0002", "第一行");
         properties.put("E_0003", "脚注解析异常");
         // 图片字符串
         properties.put("P01", "data:image/jpg;base64,"+"图片转换的字符串") ;
         WordUtil.changWord(is, properties, 140, 400);
}
}
  
