导出docx为字节流
导出docx为字节流
注释:由于poi-tl对循环列表的导出说明的不是很详细,故此处导出时使用poi和poi-tl结合导出。
基本思路为:使用poi导出文本和列表,存为临时文件,再以临时文件为模板,使用poi-tl导出图表,最终生成导出结果。
应注意把临时文件删除
@ResponseBody
@GetMapping("/docx/{id}")
public Object wordExport(@PathVariable Integer id,HttpServletResponse re) throws Exception {
Map<String,Object> infos = service.docxInfos(id);//文本
Map<String,List<Map<String,Object>>> infolist = new HashMap<>();
infolist.put("tool", service.toolInfos(id));//列表
//如果模板是本地文件,可将本地文件转化为 FileInputStream
// FileInputStream in = new FileInputStream("C:\\Users\\Desktop\\e2\\模板 .docx");
WordDocxWriter docx = new WordDocxWriter( //此处将模板文件实例化为WordDocxWriter类
// in);
//如果模板保存在maven项目的资源文件中,可通过 .class.getResourceAsStream("/static/template/projectExportTemplate.docx") 可获取到文件流
ExportController.class.getResourceAsStream("/static/template/projectExportTemplate.docx"));
docx.setMarker(infos).setMarkers(infolist); //此处将文本和列表写入模板
byte[] bytes = docx.getBytes(); //模板写入后转为字节流
File tmp = CstDirs.getDir(CstDir.tmp); //获取本地临时文件保存路径
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");//获取当前17位时间戳
File xdoc = new File(tmp,id+sdf.format(new Date())+".docx"); //新建临时文件,以时间戳作为临时文件名称的一部分,防止重名
FileOutputStream fos = new FileOutputStream(xdoc); //降临时文件转为FileOutputStream,以便写入
fos.write(bytes); //将模板字节流写入临时文件,此时xdoc为第一次导出的docx文件,临时文件第导模板
fos.close(); //关闭流
Map<String,Object> plinfos = new HashMap<>();
String name = "";
if(service.getById(id) != null) {
name = StringKit.of(service.getById(id).getName());
}
plinfos.put("page", name+" 文件"); //文本
plinfos.put("sPie", service.issueServerityPie(id));//饼图
plinfos.put("rBar", service.issueRuleTop10(id));//柱图
plinfos.put("bLine", service.BuildLineTop10(id));//折线图
XWPFTemplate template = XWPFTemplate.compile(xdoc).render(plinfos);//使用poi-tl的方法导出文本和图表,导出生成XWPFTemplate类型
xdoc.delete(); //删除临时文件xdoc
ByteArrayOutputStream baos = new ByteArrayOutputStream();
template.write(baos); //将template写入输出流
template.close(); //关闭template
// baos.close();
// 设置http协议头部
HttpHeaders headers = new HttpHeaders();
// 设置文件名
String fileName = "";
fileName = new String((name + "项目报告.docx").getBytes("UTF-8"), "iso-8859-1");// 为了解决中文名称乱码问题
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
re.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
return baos.toByteArray();//输出流转为字节流,用于下载
}