碰到一个需求,需要把Echarts雷达图导入到excel模板中并供下载在客户端,在网上找到过相关的列子,大概实现方案是通过echarts提供的方法得到base64编码,然后将base64传到后台处理,解析为图片存入服务器路径下,然后通过poi调用将图片插入。
但是后面发现这个方法有个缺点,就是每操作一次都要生成图片到服务器上,会消耗很大的资源,所以我选择把base64编码转成byte[]字节数组,再将字节转换为输入流得到BufferedImage,通过ImageIO写入到输出流中,然后利用HSSFPatriarch将图片写入EXCEL。
下面是相关代码:
Echarts雷达图代码
option = { title: { text: '基础雷达图' }, tooltip: {}, legend: { data: ['预算分配(Allocated Budget)', '实际开销(Actual Spending)'] }, radar: { // shape: 'circle', indicator: [ { name: '销售(sales)', max: 6500}, { name: '管理(Administration)', max: 16000}, { name: '信息技术(Information Techology)', max: 30000}, { name: '客服(Customer Support)', max: 38000}, { name: '研发(Development)', max: 52000}, { name: '市场(Marketing)', max: 25000} ] },
toolbox: {
show : true,
feature : {
mark : {show: true},
saveAsImage : {show: true}
}
},
series: [{ name: '预算 vs 开销(Budget vs spending)', type: 'radar', // areaStyle: {normal: {}}, data : [ { value : [4300, 10000, 28000, 35000, 50000, 19000], name : '预算分配(Allocated Budget)' }, { value : [5000, 14000, 28000, 31000, 42000, 21000], name : '实际开销(Actual Spending)' } ] }] };
var picinfo=myChart.getDataURL("png");//得到base64编码 然后提交到后台处理
特别注意的是:saveAsImage 和getDataURL在IE8是不支持的(暂时没有找到解决方案)
然后就是后台处理base编码并写入到excel中,然后下载到客户端代码
/** * 批量导出领导考核信息 * * @author ouw * @param request * @param picInfoZzSzldt * @param picInfoLdlSzldt * @return */ @RequestMapping(value = "assessmentAction/exportAssessLeaderList.action") public void exportAssessLeaderList(HttpServletRequest request,HttpServletResponse response) throws IOException,WriteException{ JSONObject jsonObject = new JSONObject(); try { // 生成图片 byte[] picInfoByte= base64TObyte(request, request.getParameter("picinfo"));// base64转换为byte[]// excel模板路径 String fileName = "导出模板.xls"; fileName = new String(fileName.getBytes("UTF-8"), "utf-8"); String dir = request.getSession().getServletContext() .getRealPath("/download/point"); String path = dir + "/" + fileName; File fi = new File(path); POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(fi)); // 读取excel模板 HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFSheet sheet = wb.getSheetAt(0); // 在相应的单元格进行赋值 sheet.getRow(0).getCell(0).setCellValue("写入数据"); //雷达图通过流的形式插入到excel模板中 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); // 将图片写入流中 ByteArrayInputStream in = new ByteArrayInputStream(picInfoByte); //将picInfoByte作为输入流; BufferedImage bufferImg = ImageIO.read(in); //将in作为输入流,读取图片存入image中,而这里in可以为ByteArrayInputStream(); ImageIO.write(bufferImg, "PNG", outStream); // 利用HSSFPatriarch将图片写入EXCEL HSSFPatriarch patri = sheet.createDrawingPatriarch(); HSSFClientAnchor anchor = new HSSFClientAnchor(4, 4, 4, 4, (short) 0, 6, (short) 4, 23); patri.createPicture(anchor, wb.addPicture( outStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG)); try { wb.write(outStream); outStream.flush(); outStream.close(); wb.write(outStream2); outStream2.flush(); outStream2.close(); } catch (IOException e) { e.printStackTrace(); } //输出Excel文件 (用户客户端下载) OutputStream output=response.getOutputStream(); response.reset(); response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename="导出名称.xls").getBytes(), "iso-8859-1")); wb.write(output); output.close(); } catch (Exception e) { e.printStackTrace(); } finally { } String json = jsonObject.toString(); return; } /** * base64编码转换为字节 * * @author ouw * @param fileName * @param req * @param imgsURl * @return */ public byte[] base64TObyte(HttpServletRequest req,String imgsURl) { //对字节数组字符串进行Base64解码并生成图片 byte[] buffer; if (imgsURl == null) //图像数据为空 return null; try { String[] url = imgsURl.split(","); String u = url[1]; //Base64解码 buffer = new BASE64Decoder().decodeBuffer(u); //生成图片 return buffer; } catch (Exception e) { System.out.println(e); return null; } }
如遇到有关问题,或者更好的方案,欢迎大家和我交流!!
