利用poi导出复杂样式的excel表格的实现。
我们要实现的效果是:
我们利用提前设计好模板样式,再在模板中填充数据的方式。
首先,pom.xml引入poi。
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency>
然后,编写代码部分。
@RequestMapping("/print") public void print(String param,HttpServletResponse response, HttpServletRequest request) throws Exception{ //获取模板存放的路径 String path=request.getSession().getServletContext().getRealPath("/")+"/ExcelTemplate/"; InputStream is=new FileInputStream(new File(path+"表单模板.xls")); HSSFWorkbook wb=new HSSFWorkbook(is); HSSFSheet sheet = wb.getSheetAt(0); Row nRow=null; Cell nCell=null; //行号 int rowNo=0; //列号 int colNo=1; //获取模板上的第六行单元格样式 nRow=sheet.getRow(5); //内容样式 nCell=nRow.getCell(3); CellStyle textStartStyle=nCell.getCellStyle(); nCell=nRow.getCell(5); CellStyle textCenterStyle=nCell.getCellStyle(); nCell=nRow.getCell(6); CellStyle textEndStyle=nCell.getCellStyle(); //大标题================================================ nRow=sheet.getRow(rowNo++); //获取第一行对象 nCell=nRow.getCell(colNo); //获取第一个单元格对象 nCell.setCellValue("入流入库单"); //获取第二行 colNo=1; nRow=sheet.getRow(rowNo++); nCell=nRow.getCell(colNo++);//第二行第二列 nCell.setCellValue("测试客户"); nCell=nRow.getCell(colNo+=3);//第二行第四列 nCell.setCellValue("2018-09-18"); //获取第三行 colNo=1; nRow=sheet.getRow(rowNo++); nCell=nRow.getCell(colNo++);//第三行第二列 nCell.setCellValue("豫A 123"); nCell=nRow.getCell(colNo+=3);//第三行第四列 nCell.setCellValue("-18"); //获取第四行 colNo=1; nRow=sheet.getRow(rowNo++); nCell=nRow.getCell(colNo++);//第四行第二列 nCell.setCellValue("郑州"); nCell=nRow.getCell(colNo+=3);//第四行第四列 nCell.setCellValue("漯河"); //插入行 for(int j=0;j<2;j++){ colNo=0; rowNo++; sheet.shiftRows(rowNo, sheet.getLastRowNum(), 1,true,false); nRow=sheet.createRow(rowNo); nCell=nRow.createCell(colNo++); nCell.setCellValue("1"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("小苹果"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("1kg/袋"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("100"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("1000"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("仓库1"); nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++); nCell.setCellValue("beizhu"); nCell.setCellStyle(textEndStyle); } //换行 rowNo++; //获取第六行 nRow=sheet.getRow(rowNo++); nCell=nRow.getCell(4); nCell.setCellValue("150"); nCell=nRow.getCell(5); nCell.setCellValue("900"); //下载 DownloadUtil dUtil=new DownloadUtil(); ByteArrayOutputStream os=new ByteArrayOutputStream(); wb.write(os); dUtil.download(os, response, "测试单.xls"); os.flush(); os.close(); }
其中,"表单模板.xls"是提前设计维护好的excel,例如:
该模板放置路径,与代码中需要一致,例如存放地址为:
download.java工具类内容如下:
package cn.tf.jk.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class DownloadUtil { /** * @param filePath 要下载的文件路径 * @param returnName 返回的文件名 * @param response HttpServletResponse * @param delFlag 是否删除文件 */ protected void download(String filePath,String returnName,HttpServletResponse response,boolean delFlag){ this.prototypeDownload(new File(filePath), returnName, response, delFlag); } /** * @param file 要下载的文件 * @param returnName 返回的文件名 * @param response HttpServletResponse * @param delFlag 是否删除文件 */ protected void download(File file,String returnName,HttpServletResponse response,boolean delFlag){ this.prototypeDownload(file, returnName, response, delFlag); } /** * @param file 要下载的文件 * @param returnName 返回的文件名 * @param response HttpServletResponse * @param delFlag 是否删除文件 */ public void prototypeDownload(File file,String returnName,HttpServletResponse response,boolean delFlag){ // 下载文件 FileInputStream inputStream = null; ServletOutputStream outputStream = null; try { if(!file.exists()) return; response.reset(); //设置响应类型 PDF文件为"application/pdf",WORD文件为:"application/msword", EXCEL文件为:"application/vnd.ms-excel"。 response.setContentType("application/octet-stream;charset=utf-8"); //设置响应的文件名称,并转换成中文编码 //returnName = URLEncoder.encode(returnName,"UTF-8"); returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1")); //保存的文件名,必须和页面编码一致,否则乱码 //attachment作为附件下载;inline客户端机器有安装匹配程序,则直接打开;注意改变配置,清除缓存,否则可能不能看到效果 response.addHeader("Content-Disposition", "attachment;filename="+returnName); //将文件读入响应流 inputStream = new FileInputStream(file); outputStream = response.getOutputStream(); int length = 1024; int readLength=0; byte buf[] = new byte[1024]; readLength = inputStream.read(buf, 0, length); while (readLength != -1) { outputStream.write(buf, 0, readLength); readLength = inputStream.read(buf, 0, length); } } catch (Exception e) { e.printStackTrace(); } finally { try { outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } //删除原文件 if(delFlag) { file.delete(); } } } /** * by tony 2013-10-17 * @param byteArrayOutputStream 将文件内容写入ByteArrayOutputStream * @param response HttpServletResponse 写入response * @param returnName 返回的文件名 */ public void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException{ response.setContentType("application/octet-stream;charset=utf-8"); returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1")); //保存的文件名,必须和页面编码一致,否则乱码 response.addHeader("Content-Disposition", "attachment;filename=" + returnName); response.setContentLength(byteArrayOutputStream.size()); ServletOutputStream outputstream = response.getOutputStream(); //取得输出流 byteArrayOutputStream.writeTo(outputstream); //写到输出流 byteArrayOutputStream.close(); //关闭 outputstream.flush(); //刷数据 } }
前端调用:
var url = "newOrderCtrl/print"; postHref(url,param);//param是传输过去的参数,如果没有的话可以为空
jquery中postHref:
function postHref(url,param){ if(param && url){ var form = $("<form>"); //定义一个form表单 form.attr('style','display:none'); //在form表单中添加查询参数 form.attr('method','post'); form.attr('action',url); var $param = $("<input type='text' name='param' />"); $param.attr('value',JSON.stringify(param)); form.append($param); form.appendTo('body'); form.css('display','none'); form.submit(); }else{ console.log("url或param为空!"); return false; } }