有些公司报表、周表之类的业务需求,就可能要求开发人员不仅要展示效果(百度echarts图表插件等,不是本文的主题)还要导出各种Office文档。
接下来的实例主要是导出Excel文件
首先引入`maven依赖
org.apache.poi
poi
RELEASE
org.apache.poi
poi-ooxml
RELEASE
合并需要的单元格,设置样式,如颜色字体大小,绑定数据,以下是示例代码
//sheet名
String sheetName = "周报表";
//创建HSSFWorkbook
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sheetName);
//合并单元格,一下参数(int firstRow, int lastRow, int firstCol, int lastCol)
sheet.addMergedRegion(new CellRangeAddress(1, 7, 0, 0)); //即合并从2到8行,1到1列
//设置列宽
sheet.setColumnWidth(2, 4400); //设置第三列宽,即C列宽
// 设置样式,如果需要多种样式就多创建几个style对象
HSSFCellStyle style = wb.createCellStyle();
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
//设置字体颜色
HSSFFont font = wb.createFont();
// font.setColor((short) 12); //这个用的是short类型的颜色,具体不太懂颜色怎么配
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);// 设置字体大小
style.setFont(font); //把字体样式设置进上面创建的样式
//创建行对象,特别需要注注注意,每一行只能创建一个对象(否则重复创建会覆盖)
HSSFRow row0 = sheet.createRow(0); //第一行的对象
//创建单元格对象
HSSFCell cell = row0.createCell(0);//注意,合并的单元格只需要创建一个小格就行
cell.setCellValue("周执行报表"); //设值
cell.setCellStyle(style); //加样式
//导出文件,两种方式
//第一种,导出浏览器(就是下载嘛)
try {
try {
fileName = new String(fileName.getBytes(), "ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName); //fileName自定义导出名称
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
OutputStream os = response.getOutputStream();
wb.write(os);
os.flush();
os.close();
//第二种,导出固定文件夹
String pathname = request.getSession().getServletContext().getRealPath("/") + fileName; //fileName自定义导出名称
File dstFile = new File(pathname);
FileOutputStream out = new FileOutputStream(dstFile);
wb.write(out);
out.flush();
out.close();
总结一下,如果单元格的数据分散且多,就会导致手写的代码量非常的大。。。
还是以导Excel文件为例,这里简单讲一下,创建freemarker模板文件
1.先拿到Excel的模板文档(以导出该文档为模板)如weekly.xls
2.然后用MS Office/WPS导出xml
3.最后改成weekly.ftl
4.把weekly.ftl放置到resources文件夹的template //位置不唯一哦
5.weekly.ftl里面把所有需要绑定后台数据的改成占位符: ${(mapData.data)!}
引入依赖。
注意:如果有bean创建报错,说明可能引入冲突了,比如有些SpringBoot项目就已经集成或者引入了freemarker,如果再引入下面依赖造成bean创建不成功,项目启动不了。
org.freemarker
freemarker
2.3.22
接下来是代码时间,coding
//创建配置实例
Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
//设置编码
configuration.setDefaultEncoding("UTF-8");
//ftl模板文件
configuration.setClassForTemplateLoading(ExcelUtil.class, "/");
//获取模板
Template template = configuration.getTemplate(templateName); //模板位置,如templates/weekly.ftl
Map map = new HashMap();
Map map1 = new HashMap();
map1.put("data", "你的数据在这里");
map.put("mapData", map1); //自定义的key数据名称
//将模板和数据模型合并生成文件
//输出文件
//单文件下载直接输出浏览器
try {
try {
fileName = new String((fileName + "").getBytes(), "ISO8859-1"); //fileName自定义文件名
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
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");
} catch (Exception ex) {
ex.printStackTrace();
}
OutputStream os = response.getOutputStream();
template.process(map, new OutputStreamWriter(os));
os.flush();
os.close();
以后如果有接触到新的方法,本人尽量会加到这里来