POI导出word

摘要:
最近,有一个项目需要用作导出单词的功能。在写作之初,人们发现poi对word的支持确实很差。仍然建议您使用xml或其他方式导出word。此功能在两个博客中显示。如果你需要使用poi,你可以看到这个博客。欢迎添加。

最近有一个项目需要用做导出word的功能,刚开始用的是poi,开始写的时候才发现poi对于word的支持真的是少的可怜,还是推荐大家用xml或者别的来做导出word,本次功能分两篇博客展现如果用需要用poi的可以看看这篇博客,欢迎补充。

  1. 替换word表格参数
  2. 动态生成行

根据word模板导出word

public class WordUtil {
 /**
 	* 这是一个工具类
     * 替换所有段落中的标记
     *
     * @param xwpfParagraphList
     * @param params
     */
    public static void replaceInAllParagraphs(List<XWPFParagraph> xwpfParagraphList, Map<String, String> params) {
        for (XWPFParagraph paragraph : xwpfParagraphList) {
            if (paragraph.getText() == null || paragraph.getText().equals("")) continue;
            for (String key : params.keySet()) {
                if (paragraph.getText().contains(key)) {
                    replaceInParagraph(paragraph, key, params.get(key));
                }
            }
        }
    }
 
    /**
     * 替换段落中的字符串
     *
     * @param xwpfParagraph
     * @param oldString
     * @param newString
     */
    public static void replaceInParagraph(XWPFParagraph xwpfParagraph, String oldString, String newString) {
        Map<String, Integer> pos_map = findSubRunPosInParagraph(xwpfParagraph, oldString);
        if (pos_map != null) {
            List<XWPFRun> runs = xwpfParagraph.getRuns();
            XWPFRun modelRun = runs.get(pos_map.get("end_pos"));
            XWPFRun xwpfRun = xwpfParagraph.insertNewRun(pos_map.get("end_pos") + 1);
            xwpfRun.setText(newString);
            if (modelRun.getFontSize() != -1)
                xwpfRun.setFontSize(modelRun.getFontSize());//默认值是五号字体,但五号字体getFontSize()时,返回-1
            xwpfRun.setFontFamily(modelRun.getFontFamily());
            for (int i = pos_map.get("end_pos"); i >= pos_map.get("start_pos"); i--) {
                xwpfParagraph.removeRun(i);
            }
        }
    }
 
    /**
     * 找到段落中子串的起始XWPFRun下标和终止XWPFRun的下标
     *
     * @param xwpfParagraph
     * @param substring
     * @return
     */
    public static Map<String, Integer> findSubRunPosInParagraph(XWPFParagraph xwpfParagraph, String substring) {
        List<XWPFRun> runs = xwpfParagraph.getRuns();
        int start_pos = 0;
        int end_pos = 0;
        String subtemp = "";
        for (int i = 0; i < runs.size(); i++) {
            subtemp = "";
            start_pos = i;
            for (int j = i; j < runs.size(); j++) {
                if (runs.get(j).getText(runs.get(j).getTextPosition()) == null) continue;
                subtemp += runs.get(j).getText(runs.get(j).getTextPosition());
                if (subtemp.equals(substring)) {
                    end_pos = j;
                    Map<String, Integer> map = new HashMap<>();
                    map.put("start_pos", start_pos);
                    map.put("end_pos", end_pos);
                    return map;
                }
            }
        }
        return null;
    }
 
    /**
     * 替换所有的表格
     *
     * @param xwpfTableList
     * @param params
     */
    public static void replaceInTables(List<XWPFTable> xwpfTableList, Map<String, String> params) {
        for (XWPFTable table : xwpfTableList) {
            replaceInTable(table, params);
        }
    }
 
    /**
     * 替换一个表格中的所有行
     *
     * @param xwpfTable
     * @param params
     */
    public static void replaceInTable(XWPFTable xwpfTable, Map<String, String> params) {
        List<XWPFTableRow> rows = xwpfTable.getRows();
        replaceInRows(rows, params);
    }
 
    /**
     * 替换表格中的一行
     *
     * @param rows
     * @param params
     */
    public static void replaceInRows(List<XWPFTableRow> rows, Map<String, String> params) {
        for (int i = 0; i < rows.size(); i++) {
            XWPFTableRow row = rows.get(i);
            replaceInCells(row.getTableCells(), params);
        }
    }
 
    /**
     * 替换一行中所有的单元格
     *
     * @param xwpfTableCellList
     * @param params
     */
    public static void replaceInCells(List<XWPFTableCell> xwpfTableCellList, Map<String, String> params) {
        for (XWPFTableCell cell : xwpfTableCellList) {
            replaceInCell(cell, params);
        }
    }
 
    /**
     * 替换表格中每一行中的每一个单元格中的所有段落
     *
     * @param cell
     * @param params
     */
    public static void replaceInCell(XWPFTableCell cell, Map<String, String> params) {
        List<XWPFParagraph> cellParagraphs = cell.getParagraphs();
        replaceInAllParagraphs(cellParagraphs, params);
     }
    }

下面是调用方法 因为map泛型规定了String,所以非String类型的参数都要用""串接起来

public static void main(String[] args) {
        Map<String, String> params = new HashMap<>();
        params.put("${name}", "请假");
        params.put("${user}", "邹某");
        params.put("${time}", "" + new SimpleDateFormat("yyyy-MM-dd hh:mm").format(new Date()) + "");
        params.put("${type}", "产假");
        params.put("${project}", "金融");
        params.put("${startTime}", "2018-12-05 12:00");
        params.put("${endTime}", "2018-12-05 12:00");
        params.put("${dept}", "开发部");
        params.put("${numDay}", "1");
        params.put("${remark}", "不想上班");
        String filepath = "E:\test.docx";
        String destpath = "E:\test3.docx";
        WordUtil wordUtil = new WordUtil();
      WordUtil wordUtil = new WordUtil();
        try {
            OPCPackage pack = POIXMLDocument.openPackage(filepath);//读取模板文件
            XWPFDocument document = new XWPFDocument(pack);//创建word文件并将模板导入
            //对段落中的标记进行替换
        	List<XWPFParagraph> parasList = xwpfDocument.getParagraphs();
        	replaceInAllParagraphs(parasList, map);
            //表格标记替换
            List<XWPFTable> tables = document.getTables();
            wordUtil.replaceInTables(tables, params);
            FileOutputStream  outStream = new FileOutputStream(destpath);
            document.write(outStream);
            outStream.flush();
            outStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

POI导出word第1张

POI导出word第2张

以上就是poi替换word模板参数的所有内容,欢迎补充

免责声明:文章转载自《POI导出word》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇动态生成与编译(一)入门5.5Python数据处理篇之Sympy系列(五)---解方程下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring MVC重定向和转发及异常处理

SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向。而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器。对于请求转发的页面,也可以是WEB-INF中页面;对于重定向的页面,不能为WEB-INF中的页面。因为重定向相当于用户再次发出一次请求,而用户是不能直接访问WEB...

android: 记录app运行过程中产生的log

有时在解决问题时,经常需要借助logcat才能分析定位问题,这里写了一个小工具,能够记录app运行期间的log, 这样测试人员在反馈bug时,只需要把logcat发给我们就可以了。具体代码如下: import android.content.Context; import android.content.Intent; import android.net...

消息队列之 ActiveMQ

简介 ActiveMQ 特点 ActiveMQ 是由 Apache 出品的一款开源消息中间件,旨在为应用程序提供高效、可扩展、稳定、安全的企业级消息通信。 它的设计目标是提供标准的、面向消息的、多语言的应用集成消息通信中间件。ActiveMQ 实现了 JMS 1.1 并提供了很多附加的特性,比如 JMX 管理、主从管理、消息组通信、消息优先级、延迟接收...

JAVA基础4---序列化和反序列化深入整理(JDK序列化)

一、什么是序列化和反序列化? 序列化:将对象状态信息转化成可以存储或传输的形式的过程(Java中就是将对象转化成字节序列的过程) 反序列化:从存储文件中恢复对象的过程(Java中就是通过字节序列转化成对象的过程) 二、为什么要序列化和反序列化? Java中对象都是存储在内存中,准确地说是JVM的堆或栈内存中,可以各个线程之间进行对象传输,但是无法在进程之间...

Haskell语言学习笔记(23)MonadReader, Reader, ReaderT

MonadReader 类型类 class Monad m => MonadReader r m | m -> r where ask :: m r ask = reader id local :: (r -> r) -> m a -> m a reader :: (r -> a)...

基于Geomesa服务查询轨迹数据无法根据空间和时间范围进行结果查询

一、Geomesa - QuickStart(教程工程包) 百度网盘下载地址:geomesa-tutorials-master.7z 二、解压后,IDEA编译如下 百度网盘下载地址:IDEA2018破解版安装 三、根据日期范围查询 1 @Test 2 public void query() throwsException { 3 4...