利用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(); Row nRow=null;
Cell nCell=null; //行号
int rowNo=;
//列号
int colNo=; //获取模板上的第六行单元格样式
nRow=sheet.getRow();
//内容样式
nCell=nRow.getCell();
CellStyle textStartStyle=nCell.getCellStyle();
nCell=nRow.getCell();
CellStyle textCenterStyle=nCell.getCellStyle();
nCell=nRow.getCell();
CellStyle textEndStyle=nCell.getCellStyle(); //大标题================================================
nRow=sheet.getRow(rowNo++); //获取第一行对象
nCell=nRow.getCell(colNo); //获取第一个单元格对象
nCell.setCellValue("入流入库单");
//获取第二行
colNo=;
nRow=sheet.getRow(rowNo++);
nCell=nRow.getCell(colNo++);//第二行第二列
nCell.setCellValue("测试客户");
nCell=nRow.getCell(colNo+=);//第二行第四列
nCell.setCellValue("2018-09-18");
//获取第三行
colNo=;
nRow=sheet.getRow(rowNo++);
nCell=nRow.getCell(colNo++);//第三行第二列
nCell.setCellValue("豫A 123");
nCell=nRow.getCell(colNo+=);//第三行第四列
nCell.setCellValue("-18");
//获取第四行
colNo=;
nRow=sheet.getRow(rowNo++);
nCell=nRow.getCell(colNo++);//第四行第二列
nCell.setCellValue("郑州");
nCell=nRow.getCell(colNo+=);//第四行第四列
nCell.setCellValue("漯河"); //插入行
for(int j=;j<;j++){
colNo=;
rowNo++;
sheet.shiftRows(rowNo, sheet.getLastRowNum(), ,true,false);
nRow=sheet.createRow(rowNo); nCell=nRow.createCell(colNo++);
nCell.setCellValue("");
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("");
nCell.setCellStyle(textCenterStyle); nCell=nRow.createCell(colNo++);
nCell.setCellValue("");
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();
nCell.setCellValue("");
nCell=nRow.getCell();
nCell.setCellValue(""); //下载
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 = ;
int readLength=;
byte buf[] = new byte[];
readLength = inputStream.read(buf, , length);
while (readLength != -) {
outputStream.write(buf, , readLength);
readLength = inputStream.read(buf, , 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;
}
}

参考地址:https://blog.csdn.net/sdksdk0/article/details/53393453

源码下载地址:https://github.com/sdksdk0/JK

最新文章

  1. YY前端课1
  2. 笔记本win8,mac10.10,ubuntu,android四系统安装
  3. canvas对象arcTo函数的使用-遁地龙卷风
  4. 纯代码TableView自适应高度(很老的使用方法)
  5. 用PHP实现URL转换短网址的算法示例
  6. UpdatePanel AsyncPostBackTrigger PostBackTrigger 区别
  7. iOS 系统二维码扫描(可限制扫描区域)
  8. mysql open files
  9. Log4net 写文件日志与数据库日志
  10. 最逼近Mac OS的Linux系统 -- Elementary OS
  11. Oracle 当前时间加减
  12. C#日志工具汇总
  13. SZU:G34 Love code
  14. codeforces 887B Cubes for Masha 两种暴力
  15. Lintcode249 Count of Smaller Number before itself solution 题解
  16. 自定义UICollectionViewLayout 布局实现瀑布流
  17. 一个简单的TensorFlow可视化MNIST数据集识别程序
  18. Form的is_valid校验规则及验证顺序
  19. TCP编程实践小结1
  20. Docker2之Service

热门文章

  1. Leetcode之回溯法专题-216. 组合总和 III(Combination Sum III)
  2. vue实现手机号码的校验(防抖函数的应用场景)
  3. 第三篇 视觉里程计(VO)的初始化过程以及openvslam中的相关实现详解
  4. java基础-多线程二
  5. UVA P12101 【Prime Path】
  6. 【管理学】PDCA
  7. The Suspects POJ1611
  8. Orders POJ - 1731
  9. vsnprint参数和意义
  10. scala函数式编程(二) scala基础语法介绍