碰到一個需求,需要把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; } }
如遇到有關問題,或者更好的方案,歡迎大家和我交流!!