首先准备maven依赖
1 <dependency>
2 <groupId>org.jxls</groupId>
3 <artifactId>jxls</artifactId>
4 <version>2.2.8</version>
5 </dependency>
6 <dependency>
7 <groupId>org.jxls</groupId>
8 <artifactId>jxls-poi</artifactId>
9 <version>1.0.6</version>
10 </dependency>
11 <dependency>
12 <groupId>org.jxls</groupId>
13 <artifactId>jxls-jexcel</artifactId>
14 <version>1.0.6</version>
15 </dependency>
16 <dependency>
17 <groupId>org.jxls</groupId>
18 <artifactId>jxls-reader</artifactId>
19 <version>2.0.1</version>
20 </dependency>
然后制作模板,制作模板有一些注意事项,也是必须做到符合jxls语法命令的,否则无法动态生成
Excel模板样例
Excel模板标记在jxls中的作用分为三部分:
1、bean属性标记
2、XLS Area定义标记
3、XLS Command表示标记
- bean属性标记
jxls使用 Apache JEXL表达式语言来解析定义在excel模板中的表达式。JEXL与JSTL相似,并对JSTL进行了扩展。eg:
${department.chief.age} //属性可以是无限深度
${utils:dateFmt(date,"yyyy-MM-dd")} //自定义工具函数
- XLS Area定义标记
XLS Area 是JxlsPlus中的一个重要概念,它代表excel模板中需要被解析的矩形区域,由A1到最后一个单元格表示,有利于加快解析速度。
XLS Area 使用excel注释标注表示,它需要被定义在excel 模板的第一个单元格(A1):
jx:area(lastCell = "<AREA_LAST_CELL>")
这个标记定义了excel模板需要被解析的矩形区域为:A1到<AREA_LAST_CELL>。
- XLS Command表示标记
XLS Command 使用excel注释标注表示,命令格式如下:
jx:<command_name>(attr1='val1' attr2='val2' ... attrN='valN' lastCell=<last_cell> areas=["<command_area1>", "<command_area2",
... "<command_areaN>"])
<command_name> 是库自带的命名或是用户自定义并注册到XlsCommentAreaBuilder的命令。
each 命令是最常用的XLS命令,形如:
jx:each(items="employees" var="employee" lastCell="D4")
each 可以有如下一些属性:
- items 上下文中集合的变量名;
- var 在遍历集合的时候每一条记录的变量名;
- area 该XLS Command的解析区域;
- direction 数据在excel中填充的方向,默认(DOWN)向下;
- select 其值为一个表达式,用来过滤数据。
jexl自定义工具函数
如果你需要自定jexl来处理数据,你可以从Transformer对象获取JexlEngine引用,并对其配置。
下面的例子实现了将一个自定义jexl函数注册到utils命名空间下:
1 JxlsHelper jxlsHelper = JxlsHelper.getInstance();
2
3 Transformer transformer = jxlsHelper.createTransformer(is, os);
4
5 JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
6
7 Map<String, Object> funcs = new HashMap<String, Object>();
8
9 funcs.put("utils", new JxlsUtils()); //添加自定义功能
10
11 evaluator.getJexlEngine().setFunctions(funcs);
接下来就是代码的实现 一个完成的工具类。
1 package com.sgcc.mall.onestop.utils;
2 import com.sgcc.mall.core.entitys.DejNgOrder;
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 public class ExportUtil {
11 //文件保存位置 TODO
12 private static String url = "D:\tools";
13
14 public static void outExportFile(List billInfo) throws IOException {
15
16 Map<String,Object> map = new HashMap<String, Object>();
17 map.put("billInfo", billInfo);
18 //获取模板所在位置 TODO
19 String filePath = "D:\template.xls";
20 //导出文件名称
21 String fileName = "demo";
22 File file = FreeMarkerFileUtil.getPdfFile(filePath,fileName,map);
23 FreeMarkerFileUtil.outFile(file,url);
24 }
25
26 public static void main(String[] args) {
27 List<NgOrder> ngOrders = new ArrayList<NgOrder>();
28 NgOrder d = new NgOrder();
29 d.setBrand("海尔");
30 ngOrders.add(d);
31 try {
32 outExportFile(ngOrders);
33 } catch (IOException e) {
34 e.printStackTrace();
35 }
36 }
37 }
1 package com.sgcc.mall.onestop.utils;
2
3 import com.aspose.cells.License;
4 import com.aspose.cells.SaveFormat;
5 import com.aspose.cells.Workbook;
6 import org.apache.log4j.Logger;
7 import org.jxls.common.Context;
8 import org.jxls.util.JxlsHelper;
9
10 import javax.servlet.ServletOutputStream;
11 import javax.servlet.http.HttpServletResponse;
12 import java.io.*;
13 import java.net.URLEncoder;
14 import java.util.Map;
15
16
17 public final class FreeMarkerFileUtil {
18 private static Logger log = Logger.getLogger(FreeMarkerFileUtil.class);
19
20 public static final String UTF8 = "utf-8";
21 /**
22 * 生成execl文件后缀名
23 */
24 public static final String XLS_SUFFIX = ".xls";
25 /**
26 * 生成pdf文件后缀名
27 */
28 public static final String PDF_SUFFIX = ".pdf";
29 /**
30 * 向浏览器输出execl文件类型,用于指定响应头信息
31 */
32 public static final int XLS_OUT_TYPE = 1;
33 /**
34 * 向浏览器输出execl文件响应头信息
35 */
36 public static final String XLS_CONTENT_TYPE = "application/vnd.ms-excel;charset=" + UTF8;
37 /**
38 * 向浏览器输出pdf文件类型,用于指定响应头信息
39 */
40 public static final int PDF_OUT_TYPE = 2;
41 /**
42 * 向浏览器输出pdf文件响应头信息
43 */
44 public static final String PDF_CONTENT_TYPE = "application/pdf;charset=" + UTF8;
45
46
47 /**
48 * 根据指定模板生成execl文件
49 *
50 * @param tmpFilePath 模板文件
51 * @param fileName 文件名称
52 * @param beans 模板填充数据集
53 * @return
54 */
55 public static File getXlsFile(String tmpFilePath, String fileName, Map beans) throws IOException {
56 File xlsFile = File.createTempFile(fileName, XLS_SUFFIX);
57 Context context = new Context();
58 context.putVar("beans", beans);
59 log.info("进入数据填充");
60 JxlsHelper.getInstance().processTemplate(new FileInputStream(tmpFilePath), new FileOutputStream(xlsFile), context);
61 log.info("数据填充完成");
62 return xlsFile;
63 }
64
65 /**
66 * 根据指定模板生成execl的PDF格式文件
67 *
68 * @param tmpFilePath 模板文件
69 * @param fileName 文件名称
70 * @param beans 模板填充数据集
71 * @return
72 */
73 public static File getPdfFile(String tmpFilePath, String fileName, Map beans) throws IOException {
74 // 根据模板获取execl文件
75 File xlsFile = getXlsFile(tmpFilePath, fileName, beans);
76 File pdfFile = execl2Pdf(xlsFile, fileName);
77 return pdfFile;
78 }
79
80 /**
81 * execl文件转换为pdf文件
82 *
83 * @param xlsFile execl文件
84 * @param pdfFileName 生成的pdf文件名称
85 * @return
86 */
87 public static File execl2Pdf(File xlsFile, String pdfFileName) {
88 // 验证License
89 if (!getLicense()) {
90 throw new RuntimeException("验证License失败!");
91 }
92 try {
93 InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(xlsFile), "UTF-8");
94 Workbook wb = new Workbook(new FileInputStream(xlsFile));
95 File pdfFile = File.createTempFile(pdfFileName, PDF_SUFFIX);
96 // 输出路径
97 FileOutputStream fileOS = new FileOutputStream(pdfFile);
98 wb.save(fileOS, SaveFormat.PDF);
99 return pdfFile;
100 } catch (Exception e) {
101 e.printStackTrace();
102 }
103 return null;
104 }
105
106 /**
107 * 输出文件到浏览器
108 *
109 * @param file 需要输出的文件
110 * @param fileName 输出的文件名
111 * @param response
112 * @param type 输出的文件类型
113 * @throws IOException
114 */
115 public static void outFile(File file, String fileName, HttpServletResponse response, int type) throws IOException {
116 try {
117 fileName = URLEncoder.encode(fileName, UTF8);
118 } catch (UnsupportedEncodingException e) {
119 e.printStackTrace();
120 throw new RuntimeException("不支持的编码格式:" + UTF8);
121 }
122
123 response.reset();
124 //设置响应文本格式
125 if (type == XLS_OUT_TYPE) {
126 response.setContentType(XLS_CONTENT_TYPE);
127 } else if (type == PDF_OUT_TYPE) {
128 response.setContentType(PDF_CONTENT_TYPE);
129 } else {
130 throw new RuntimeException("类型错误");
131 }
132 response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes(), "iso-8859-1"));
133 InputStream bis = null;
134 OutputStream bos = null;
135 try {
136 //将文件输出到页面
137 ServletOutputStream out = response.getOutputStream();
138 bis = new BufferedInputStream(new FileInputStream(file));
139 bos = new BufferedOutputStream(out);
140 byte[] buff = new byte[1024];
141 int bytesRead;
142 // 根据读取并写入
143 while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
144 bos.write(buff, 0, bytesRead);
145 }
146 } finally {
147 if (bis != null) {
148 bis.close();
149 }
150 if (bos != null) {
151 bos.close();
152 }
153 }
154
155 }
156
157 /**
158 * 输出文件到本地磁盘
159 *
160 * @param file
161 * @param outDir
162 * @throws IOException
163 */
164 public static void outFile(File file, String outDir) throws IOException {
165 InputStream bis = null;
166 OutputStream bos = null;
167 try {
168 bis = new BufferedInputStream(new FileInputStream(file));
169 bos = new BufferedOutputStream(new FileOutputStream(outDir + file.getName()));
170 byte[] buff = new byte[2048];
171 int bytesRead;
172 // 根据读取并写入
173 while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
174 bos.write(buff, 0, bytesRead);
175 }
176 } finally {
177 if (null != bis) {
178 bis.close();
179 }
180 if (null != bos) {
181 bos.close();
182 }
183 }
184 }
185 /**
186 * 验证license
187 *
188 * @return
189 */
190 public static boolean getLicense() {
191 boolean result = false;
192 try {
193 InputStream is = FreeMarkerFileUtil.class.getClassLoader().getResourceAsStream("\license.xml");
194 License aposeLic = new License();
195 aposeLic.setLicense(is);
196 result = true;
197 } catch (Exception e) {
198 e.printStackTrace();
199 }
200 return result;
201 }
202 }
一个根据模板导出Excel的功能就结束了,更多复杂的功能之后继续完善,希望大家多多提意见,共同进步。