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小时内删除。
发表评论