java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
本篇文章主要介绍了 java 后台利用 Apache poi 生成 excel 文档提供前台下载示例,非常具有实用价值,需要的朋友可以参考下
之前在项目中会用到在 Java 在后台把数据填入 Word 文档的模板来提供前台下载,为了自己能随时查看当时的实现方案及方便他人学习我写了这篇博客,访问量已经是我写的博客里第一了。于是乎我在学会用 Java 在后台利用 Apache poi 生成 excel 文档提供前台下载之后就想着来写一篇姊妹篇啦。
在生成 Excel 文档的时候我采用了和生成 Word 时的不同方法,Apache poi。它是用 Java 编写的免费开源的跨平台的 Java API,提供 API 给 Java 程式对 Microsoft Office 格式档案读和写的功能。想要实现这个功能,就按照下面的步骤来做吧,为了方便起见,我直接拿项目中遇到的实例来举例说明,是的,我在写这篇博客的时候同时也在完成手上的项目。
step1: 创建 xls 格式的模板表头含有我的甲方信息就打码了,可以看到我搞了一个空的模板文件,现在有很多东西需要在后台填入
step2: 前台触发事件搞一个按钮,用户点击的时候用 JavaScript 的 window.location.href 将页面重定向到你处理下载的 URL 去
比方说,这是我项目的前台,看到那个表面质量按钮吗,来看一下当它被点击的时候调用的函数
- function exportBatch() {
- //get请求,可以传递参数,比方说我这里就传了一堆卷号,我只生成传过去的这堆卷号的检验记录
- //参数rollNumbers的细节就不展示了,业务相关
- window.location.href = '../ir/exportSurface?rollNumberList=' + rollNumbers;
- }
有朋友可能想用什么 Ajax 来发送请求,我反正是没搞出来,挺麻烦的,网上找的相关解决方案也都比较蛋疼,因此不传什么复杂的敏感的参数,就这么写就可以。
step3: 后台处理首先你当然要把 Apache poi 那一套东西引入你的项目啦,我的项目是 Maven 项目,添加依赖很容易
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>3.14</version>
- </dependency>
然后,为了方便导出 Excel,在项目中建了一个 ExcelUtils 工具类,后面给出源码,这么一来导出 Excel 会变得更简单。ExcelUtils 里面除了一些既定的方法外,还有就是你具体怎么去操作模板的方法了。当然你用的少的话可以不用我这工具类,而是在你需要的时候 import 相关的类,然后在你处理的时候就把操作模板的逻辑写进去也可以。但我这个项目很多次用到导出 Excel,所以抽象出一个工具类是很有必要的,符合设计模式。
我的项目是基于 SpringMVC 的,来看看我后台接收到请求以后做了些什么吧
Controller:
- /***
- * 批量导出表面质量检验记录
- *
- * @return
- * @throws Exception
- */
- @RequestMapping(value = "exportSurface", method = RequestMethod.GET)@ResponseBody public void exportSurface(HttpServletRequest request, HttpServletResponse response) throws Exception {
- //参数获取及处理,业务相关不展示
- //把要填写的数据放在一个map里
- Map < String,
- Object > map = new HashMap < String,
- Object > ();
- map.put("sequence", "0001"); //mock编号
- map.put("date", DateUtils.toDateStr(new Date(), DateUtils.DEFAULT_DATE_PATTERN_CHINESE));
- map.put("chetaihao", "1#"); //mock车台号
- map.put("productName", "预应力钢绞线"); //mock品名
- map.put("specification", "规格"); //mock规格
- map.put("memo", "备注"); //mock备注
- map.put("inspectRecordBizList", inspectRecodeBizList);
- ExcelUtils.exportInspectionRecordSurface(request, response, map);
- }
最后调用 ExcelUtils 里的相关导出方法,这个方法是自定义的,它定义的是怎样去操作模板
自定义的方法:
- public static void exportInspectionRecordSurface(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
- //模板的路径,这个在自己的项目中很容易弄错,相对位置一定要写对啊
- String psth = request.getRealPath("/") + INSPECTIONRECORD_SURFACE_TEMPLET_PATH;
- Workbook webBook = readExcel(psth);
- createCellStyle(webBook);
- Sheet sheet = webBook.getSheetAt(0);
- //开始操作模板,找到某行某列(某个cell),需要注意的是这里有个坑,行和列的计数都是从0开始的
- //一次数据插入的位置不对,别灰心,多试几次就好啦,你要是能看懂我下面的代码,数据插在了什么位置,你就明白了
- int rows = 1;
- Row row = sheet.getRow(rows);
- row.createCell(1).setCellValue((String) map.get("sequence"));
- row.createCell(3).setCellValue((String) map.get("date"));
- row.createCell(9).setCellValue((String) map.get("chetaihao"));
- rows = 2;
- row = sheet.getRow(rows);
- row.createCell(1).setCellValue((String) map.get("productName"));
- row.createCell(3).setCellValue((String) map.get("specification"));
- row.createCell(9).setCellValue((String) map.get("memo"));
- //检验记录的插入业务相关,不展示,其实就是for循环在合适的行合适的列插入一个个对象的属性即可,你这么聪明,没问题的
- writeExcel(response, webBook, "表面质量检验记录");
- }
ExcelUtils:
step4: 启动项目,然后测试一下,看!完美的导出了。。。有图为证
- //这里得有你自己的package名
- import org.apache.poi.hssf.usermodel.HSSFCellStyle;
- import org.apache.poi.hssf.usermodel.HSSFFont;
- import org.apache.poi.hssf.usermodel.HSSFRichTextString;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.ss.usermodel. * ;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io. * ;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- /**
- * Created by bwju on 2016/12/06.
- */
- public class ExcelUtils {
- private static final String INSPECTIONRECORD_SURFACE_TEMPLET_PATH = "/asserts/templete/InspectionRecordSurface.xls";
- private static HSSFCellStyle cellstyle = null;
- public static void exportInspectionRecordSurface(HttpServletRequest request, HttpServletResponse response, Map map) throws IOException {
- //实现上文里有,改个函数名,写你的操作模板函数吧!
- }
- private static Workbook readExcel(String filePath) {
- InputStream in =null;
- Workbook work = null;
- try { in =new FileInputStream(filePath);
- work = new HSSFWorkbook( in );
- } catch(FileNotFoundException e) {
- System.out.println("文件路径错误");
- e.printStackTrace();
- } catch(IOException e) {
- System.out.println("文件输入流错误");
- e.printStackTrace();
- }
- return work;
- }
- private static void writeExcel(HttpServletResponse response, Workbook work, String fileName) throws IOException {
- OutputStream out = null;
- try {
- out = response.getOutputStream();
- response.setContentType("application/ms-excel;charset=UTF-8");
- response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName + ".xls", "UTF-8"))));
- work.write(out);
- } catch(IOException e) {
- System.out.println("输出流错误");
- e.printStackTrace();
- } finally {
- out.close();
- }
- }
- private static Cell setCellStyleWithStyleAndValue(CellStyle style, Cell cell, String value) {
- cell.setCellStyle(style);
- cell.setCellValue(value);
- return cell;
- }
- private static Cell setCellStyleWithValue(Cell cell, String value) {
- cell.setCellStyle(cellstyle);
- cell.setCellValue(value);
- return cell;
- }
- private static Cell setCellStyleWithStyleAndValue(CellStyle style, Cell cell, RichTextString value) {
- cell.setCellStyle(style);
- cell.setCellValue(value);
- return cell;
- }
- private static Cell setCellStyleWithValue(Cell cell, int value) {
- cell.setCellStyle(cellstyle);
- cell.setCellValue(value);
- return cell;
- }
- private static Cell setCellStyleWithValue(Cell cell, double value) {
- cell.setCellStyle(cellstyle);
- cell.setCellValue(value);
- return cell;
- }
- private static HSSFCellStyle createCellStyle(Workbook wb) {
- cellstyle = (HSSFCellStyle) wb.createCellStyle();
- cellstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
- cellstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
- cellstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
- cellstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
- cellstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
- cellstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
- return cellstyle;
- }
- }
嗯嗯,文章写到这里就结束啦,Apache poi 还提供了很多 API 在本例中为得到展示,比如能够指定样式等等。
来源: http://www.phperz.com/article/18/0102/357041.html