poi 导出Excel 含多个sheet、版本问题、保存问题小解
2017-03-28 14:23
411 查看
这两天做了一个poi导出多个sheet,以及向sheet里面插入图片的功能。
前提 我们是前后端分离模式(页面上所有功能实现、数据获取都由前端实现,java仅负责写接口以供调用)
接口思路是先生成一个文件 ,保存在服务器上,返回一个url给前端,前端可以直接访问。
说下遇到的问题:
1. 版本兼容问题
我的excel版本是最新版,下载之后打开并没有问题,我同事应该是2007的,他的打开文件就弹出数据丢失提示,但是数据其实是完整的,并没有丢失。
2.保存和下载的问题
第一个问题
提示数据丢失,是老的版本有一些表达式不支持,改一下引用的包就好了。
本来我用的是 HSSFWorkbook 这个类,后来遇到第一个问题之后,换成了XSSFWorkbook这个类,2007版本打开没问题,更高版本的也可以兼容。
另外 有一个插入图片的功能,XSSFDrawing(图画管理器)都要用配套的,设置图片属性的HSSFClientAnchor类换成ClientAnchor就OK了,参数和HSSFClientAnchor类一样。
第二个问题
get请求过去访问接口就直接下载下来了,post请求更搞了,返回来的东西打印出来全都是乱码,并且在我本来用response返回输出json的那行报错了:
(java.lang.IllegalStateException: getOutputStream() has already been called for this response)
这个问题是因为同一条请求用response给了两次返回报出来的,后来仔细检查了代码,发现有个方法里面封装了这些:
设置response头信息,这几行注释掉,立马就好了,问题解决。
附上保存服务器代码段:
如果需要直接下载到本地电脑,可以加上下面这段代码,谷歌会直接保存到谷歌浏览器默认的下载地址,火狐会弹出提示框,提示用户保存或者打开。
附上代码段:
如果觉得我写的不好,可以看看这位大神的,复制出来就能用,链接:
http://www.cnblogs.com/crazyapple/p/5489588.html
插入图片详解:
http://blog.csdn.net/chenssy/article/details/20524563
下面是我导出excel的代码(导出一个Excel,包含多个sheet以及插入图片)
import java.io.IOException;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import sun.misc.BASE64Decoder;
public class ExcelUtil {
前提 我们是前后端分离模式(页面上所有功能实现、数据获取都由前端实现,java仅负责写接口以供调用)
接口思路是先生成一个文件 ,保存在服务器上,返回一个url给前端,前端可以直接访问。
说下遇到的问题:
1. 版本兼容问题
我的excel版本是最新版,下载之后打开并没有问题,我同事应该是2007的,他的打开文件就弹出数据丢失提示,但是数据其实是完整的,并没有丢失。
2.保存和下载的问题
第一个问题
提示数据丢失,是老的版本有一些表达式不支持,改一下引用的包就好了。
本来我用的是 HSSFWorkbook 这个类,后来遇到第一个问题之后,换成了XSSFWorkbook这个类,2007版本打开没问题,更高版本的也可以兼容。
另外 有一个插入图片的功能,XSSFDrawing(图画管理器)都要用配套的,设置图片属性的HSSFClientAnchor类换成ClientAnchor就OK了,参数和HSSFClientAnchor类一样。
第二个问题
get请求过去访问接口就直接下载下来了,post请求更搞了,返回来的东西打印出来全都是乱码,并且在我本来用response返回输出json的那行报错了:
(java.lang.IllegalStateException: getOutputStream() has already been called for this response)
这个问题是因为同一条请求用response给了两次返回报出来的,后来仔细检查了代码,发现有个方法里面封装了这些:
response.setContentType("application/octet-stream;charset=ISO8859-1"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.addHeader("Pargam", "no-cache"); response.addHeader("Cache-Control", "no-cache");
设置response头信息,这几行注释掉,立马就好了,问题解决。
附上保存服务器代码段:
String path = request.getServletContext().getRealPath("/");//获取当前绝对路径 String dirsName = "test";//保存Excel的文件夹名称 String filename = "xxx.xlsx";//文件名 String resultPath = path + dirName + filename; File dirs = new File(path, dirsName); if(!dirs.exists()) { dirs.mkdirs();//判断路径是否存在,不存在就创建 } FileOutputStream fout = new FileOutputStream(resultPath); wb.write(fout);//wb就是最终生成的Excel,写入到文件流中 fout.flush(); fout.close();
如果需要直接下载到本地电脑,可以加上下面这段代码,谷歌会直接保存到谷歌浏览器默认的下载地址,火狐会弹出提示框,提示用户保存或者打开。
附上代码段:
File f = new File(resultPath);//resultPath是服务器上的文件路径 if (!f.exists()) { response.sendError(404, "File not found!"); } BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; //设置http response 头信息 response.reset(); response.setContentType("application/octet-stream;"); response.setHeader("Content-Disposition", "attachment;filename="+ fileName); response.addHeader("Pargam", "no-cache"); response.addHeader("Cache-Control", "no-cache"); OutputStream out = response.getOutputStream(); while ((len = br.read(buf)) > 0) { out.write(buf, 0, len); } if (br != null) br.close(); if (out != null) out.close();
如果觉得我写的不好,可以看看这位大神的,复制出来就能用,链接:
http://www.cnblogs.com/crazyapple/p/5489588.html
插入图片详解:
http://blog.csdn.net/chenssy/article/details/20524563
下面是我导出excel的代码(导出一个Excel,包含多个sheet以及插入图片)
import java.io.IOException;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import sun.misc.BASE64Decoder;
public class ExcelUtil {
public static XSSFWorkbook getHSSFWorkbook(String[] sheetName, List<String[]> titleList, List<String[][]> valuesList, String[] img, XSSFWorkbook wb) throws IOException { // 第一步,创建一个webbook,对应一个Excel文件 if (wb == null) { wb = new XSSFWorkbook(); } // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet for (int i = 0; i < sheetName.length; i++) { XSSFSheet sheet = wb.createSheet(sheetName[i]); // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short XSSFRow row = sheet.createRow(0); // 第四步,创建单元格,并设置值表头 设置表头居中 XSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式 XSSFCell cell = null; for (int j = 0; j < titleList.get(i).length; j++) { cell = row.createCell(j); cell.setCellValue(titleList.get(i)[j]); cell.setCellStyle(style); } // 创建内容 for (int y = 0; y < valuesList.get(i).length; y++) { row = sheet.createRow(y + 1); for (int f = 0; f < valuesList.get(i)[y].length; f++) { row.createCell(f).setCellValue(valuesList.get(i)[y][f]); } } if(img[i] != null){ // 画图的顶级管理器,一个sheet只能获取一个(一定要注意这点) XSSFDrawing patriarch = sheet.createDrawingPatriarch(); // anchor主要用于设置图片的属性 ClientAnchor anchor = new XSSFClientAnchor(0, 0, 255, 255, (short) 0, valuesList.get(i).length + 2, (short) 10, 38); anchor.setAnchorType(3); BASE64Decoder decoder = new BASE64Decoder(); byte[] decoderBytes = decoder.decodeBuffer(img[i]); patriarch .createPicture(anchor, wb.addPicture(decoderBytes, HSSFWorkbook.PICTURE_TYPE_PNG)); } } return wb; }
相关文章推荐
- POI 3.8版本导出excel问题
- 关于使用POI导出时excel版本问题的bug解决
- poi工具导出excel乱码问题的解决过程
- 使用poi做excel导出时解决以文本格式存储的数字问题
- POI 多个excel 合并到同一个sheet(2003版本)
- 【poi】解决java导出excel 海量数据内存溢出问题
- 使用poi做excel导出时解决以文本格式存储的数字问题
- 使用poi低版本(poi-3.0.1)导出Excel整理
- c# datagridview 导出excel的保存问题
- Struts2导出Excel(poi)步骤及问题汇总(二) 下载
- 关于java poi导入导出excel的包冲突问题
- OWC11 SpreadsheetClass导出到Excel,文件路径的问题
- 解决poi导出excel中文列宽问题
- 导出到excel,如果不保存,会自动关闭页面的问题
- POI导出Excel文件图片丢失问题解决
- poi导出excel,可以自定义保存路径
- 使用POI导出excel,完美兼容2003及2007以上版本,购物车原理
- java excel解析:poi与jxl的区别(excel版本问题:xls,xlsx)
- 关于poi导出excel时的各种注意问题
- DevExpress asp.net 导出Excel 自动开启迅雷问题,默认保存为aspx页面