java导出word格式的⽂件
1. 使⽤POI技术⽣成word格式的⽉报,实现功能根据⽇期进⾏预览,导出。
2. 使⽤template.docx作为word模板,参数使⽤特殊符号标识,封装数据(Map<String,String>); 通过IO读取模板替换参数,从⽽动态获取
数据。
3. 预览的实现,由于web页⾯展⽰通过html或pdf来进⾏。将word转为pdf后基本都会出现样式的不兼容问题,所以放弃。最终我根据
word的模板⼜⼿写了⼀个html对应的模板,参数使⽤的jsp的el表达式动态替换参数,从⽽动态获取数据。暂时没有考虑word模板过多的情况。
4. 由于我做的系统的前端是easyui的框架,预览时的翻页使⽤了panel插件功能,批量导出使⽤的ZipEntry。
相关代码
1 package com.bocsh.base.util;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Map.Entry;
9 import java.util.Set;
10
11
12//import org.apache.poi.POIXMLDocument;
13 import org.apache.poi.xwpf.usermodel.*;
14
el表达式获取map的值15/**
16 * 通过word模板⽣成新的word⼯具类
17 *
18 * @author zhiheng
19 *
20 *
21 * XWPFDocument代表⼀个docx⽂档,其可以⽤来读docx⽂档,也可以⽤来写docx⽂档
22 * XWPFParagraph代表⽂档、表格、标题等种的段落,由多个XWPFRun组成
23 * XWPFRun代表具有同样风格的⼀段⽂本
24 * XWPFTable代表⼀个表格
25 * XWPFTableRow代表表格的⼀⾏
26 * XWPFTableCell代表表格的⼀个单元格
27 * XWPFChar 表⽰.docx⽂件中的图表
28 * XWPFHyperlink 表⽰超链接
29 * XWPFPicture 代表图⽚
30 *
31 *
32 *
33*/
34public class WorderToNewWordUtils {
35
36/**
37    * 判断表格是需要替换还是需要插⼊,判断逻辑有$为替换,表格⽆$为插⼊
38    * @param inputUrl 模板存放地址
39    * @param textMap 需要替换的信息集合
40    * @param excelDataBytes ⽣成了新的数据流  word格式,存放容器
41    * @return 成功返回true,失败返回false
42*/
43public static boolean changWord(String inputUrl,
44                                    Map<String, String> textMap, Map<String,byte[]> excelDataBytes) {
45
46//模板转换默认成功
47        boolean changeFlag = true;
48        ByteArrayOutputStream writeToBytes = null;
49try {
50//获取docx解析对象
51            XWPFDocument document = new XWPFDocument(new FileInputStream(inputUrl));
52//解析替换⽂本段落对象
53            WorderToNewWordUtils.changeText(document, textMap);
54//解析替换表格对象
55            WorderToNewWordUtils.changeTable(document, textMap);
56
57//⽣成了新的数据流  word 格式
58            writeToBytes = new ByteArrayOutputStream();
59            document.write(writeToBytes);
60            excelDataBytes.("year") + ("month"), ByteArray());
61
62        } catch (IOException e) {
63            e.printStackTrace();
64            changeFlag = false;
65        }finally{
66try {
67if(writeToBytes!=null)
68                writeToBytes.close();
69            } catch (IOException e) {
70                e.printStackTrace();
71            }
72        }
73
74return changeFlag;
75
76    }
77
78
79/**
80    * 替换段落⽂本
81    * @param document docx解析对象
82    * @param textMap 需要替换的信息集合
83*/
84public static void changeText(XWPFDocument document, Map<String, String> textMap){ 85//获取段落集合
86        List<XWPFParagraph> paragraphs = Paragraphs();
87
88for (XWPFParagraph paragraph : paragraphs) {
89//判断此段落时候需要进⾏替换
90            String text = Text();
91if(checkText(text)){
92                List<XWPFRun> runs = Runs();
93for (XWPFRun run : runs) {
94//替换模板原来位置
95                    run.setText(String(), textMap),0);
96                }
97            }
98        }
99
100    }
101
102/**
103    * 替换表格对象⽅法
104    * @param document docx解析对象
105    * @param textMap 需要替换的信息集合
106*/
107private static void changeTable(XWPFDocument document, Map<String, String> textMap){ 108//获取表格对象集合
109        List<XWPFTable> tables = Tables();
110for (int i = 0; i < tables.size(); i++) {
111//只处理⾏数⼤于等于2的表格,且不循环表头
112            XWPFTable table = (i);
Rows().size()>1){
114//判断表格是需要替换还是需要插⼊,判断逻辑有$为替换,表格⽆$为插⼊
115if(Text())){
116                    List<XWPFTableRow> rows = Rows();
117//遍历表格,并替换模板
118                    eachTable(rows, textMap);
119                }
120            }
121        }
122
123
124    }
125
126
127/**
128    * 遍历表格
129    * @param rows 表格⾏对象
130    * @param textMap 需要替换的信息集合
131*/
132private static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){ 133for (XWPFTableRow row : rows) {
134            List<XWPFTableCell> cells = TableCells();
135for (XWPFTableCell cell : cells) {
136//判断单元格是否需要替换
137if(Text())){
138                    List<XWPFParagraph> paragraphs = Paragraphs();
139for (XWPFParagraph paragraph : paragraphs) {
140                        List<XWPFRun> runs = Runs();
141for (XWPFRun run : runs) {
142                            run.setText(String(), textMap),0);
143                        }
144                    }
145                }
146            }
147        }
148    }
149
150
151/**
152    * 判断⽂本中时候包含$
153    * @param text ⽂本
154    * @return 包含返回true,不包含返回false
155*/
156private static boolean checkText(String text){
157        boolean check  =  false;
158if(text.indexOf("$")!= -1){
159            check = true;
160        }
161return check;
162
163    }
164
165/**
166    * 匹配传⼊信息集合与模板
167    * @param value 模板需要替换的区域
168    * @param textMap 传⼊信息集合
169    * @return 模板需要替换区域信息集合对应值
170*/
171private static String changeValue(String value, Map<String, String> textMap){
172        Set<Entry<String, String>> textSets = Set();
173for (Entry<String, String> textSet : textSets) {
174//匹配模板与替换值格式${key}
175            String key = "${"+Key()+"}";
176if(value.indexOf(key)!= -1){
177                value = Value();
178            }
179        }
180//模板未匹配到区域替换为空
181if(checkText(value)){
182            value = "0";
183        }
184return value;
185    }
186
187
188 }
注意:
1. html模板和word模板共⽤的数据模型
2. 写这个功能前翻阅了⼤量的关于java导出word的博客,有⼤量的将word转为ftl格式再去操作,感觉不是很⽅便和直观。
3. 上⾯的代码参考了,这⾥有使⽤POI对word⼤量的操作。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。