通过poi把echarts图表导出到excel中

点击导出的按钮(超链接)
<a class="link  myTopColor" id="exportData" href="javascript:;">导出excel</a>

 

$(function() {        
            //导出
               $("#exportData").click(function() {  
                   var myqx =document.getElementById("qxId").contentWindow.document.getElementById("myqx");
                   var myqxD = $(myqx).val();

                   var id = $("input[name='myHidId']").val();

                   var url = __ctx+'/xxx/xx/xxx/exportExcelDdrb.ht';
                            
                   var form = $("<form>");
                   form.attr("style","display:none");
                   form.attr("target","_blank");
                   form.attr("method","post");
                   form.attr("action",url);
                   var input1 = $("<input>");
                   input1.attr("type","hidden");
                   input1.attr("name","id");
                   input1.attr("value",id);
                   
                   var input2 = $("<input>");
                   input2.attr("type","hidden");
                   input2.attr("name","myqxD");
                   input2.attr("value",myqxD);
                   
                   $("body").append(form);
                   form.append(input1);
                   form.append(input2);
                   form.submit();
                   form.remove();
             
    /*                
       //open这种方式有个弊端,就是转的参数值不能太大,所以只能用jquery创建表单form在提交(ajax异步请求不会触发浏览器下载文件的功能)
           var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
              if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1) {//判断是否IE浏览器
                       window.location.href(url);
                   }else{
                       window.open(url,"调度日报");
                   }  */
                   
               }); 
               
               
        });
js代码

 

<%@page language="java" pageEncoding="UTF-8"%>
<%@include file="/commons/include/html_doctype.html"%>
<html>
<head>
<title>曲线</title>
<%@include file="/commons/include/get.jsp"%>
<script type="text/javascript" src="${ctx}/js/echarts/echarts.min.js"></script>
<style type="text/css">
</style>
</head>
<body>
    <div id="app" style="width: 600px; height: 400px;"></div> 
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var app = echarts.init(document.getElementById('app'));

        var dataX =  ${dataX}.split(",");
        var dataFhygzj =  ${dataFhygzj}.split(",");
        var dataWgygzj =  ${dataWgygzj}.split(",");

        option = {
                animation: false,
            title : {
                //text: '折线图堆叠'
                 text : '' 
            },
            tooltip : {
                trigger : 'axis'
            },
            legend : {
                data : [ '全负荷', '网供负荷' ]
            },
            grid : {
                left : '3%',
                right : '4%',
                bottom : '3%',
                containLabel : true
            },
            toolbox : {
                feature : {
                    saveAsImage : {}
                }
            },
            xAxis : {
                type : 'category',
                boundaryGap : false,
                data : dataX
            },
            yAxis : {
                type : 'value'
            },
            series : [ {
                name : '全负荷',
                type : 'line',
                stack : '总量1',
                data : dataFhygzj
            }, {
                name : '网供负荷',
                type : 'line',
                stack : '总量2',
                data : dataWgygzj
            }
            ]
        };

        app.setOption(option);
        
        $(function() {
              //获取echarts图片的base64编码字符串 pixelRatio:图片精度  backgroundColor:背景颜色
                var imgURL=app.getDataURL({
                     pixelRatio: 2,
                     backgroundColor: '#fff',
                     type: 'png'
                 });  
              /*  var imgURL=app.getDataURL("png");  */
            //alert(imgURL);
           $("#myqx").val(imgURL);
        
        });
    </script>
    
    <input type="hidden"  name="myqx"  id="myqx"  > 
</body>
</html>
iframe中的echarts相关代码

 

@RequestMapping({ "exportExcelDdrb" })
    @Action(description = "导出excel")
    public void exportExcelDdrb(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String id = RequestUtil.getString(request, "id");
        String imageMsg = RequestUtil.getString(request, "myqxD");
        // 数据格式样例myqxD="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAMgCAYAAAAz4JsCAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3Ql4VNX9xvFf2AImFGTfUdCgqKBAEYlp/WSv=";

        //取得实体类数据
        Hyddrb yjbb = new Hyddrb();
        yjbb = (Hyddrb) hyddrbService.getById(Long.valueOf(Long.parseLong(id)));
        
        String dirPath = FileUtil.getRootPath() + File.separator + "commons" + File.separator + "template" + File.separator + "hydlbbTemplate" + File.separator;
        String fileName = "expHyTabDdrb.xls";
//        String fileName = "expHyTabDdrb.xlsx";
        FileInputStream inStream = new FileInputStream(new File(dirPath + fileName));
        
        //xls2003版
        HSSFWorkbook wb = new HSSFWorkbook(inStream);
        this.drawImage(wb, imageMsg);
        this.initSheetCell(wb, yjbb);
        
        
        //xlsx2007版
//        XSSFWorkbook wbxlsx = new XSSFWorkbook(inStream);
//        this.drawImage_xlsx(wbxlsx, imageMsg);
//        this.initSheetCell_xlsx(wbxlsx, yjbb);
        
        fileName = "日报_" + new SimpleDateFormat("yyyy-MM-dd").format(yjbb.getRq()) ;
        //其实两套代码都可以,最终结果以下面给定的后缀作为生成excel的后缀,即03版还是07版
        fileName +=  ".xls";
//        fileName +=  ".xlsx";

        response.setContentType("application/excel");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes("gb2312"), "ISO8859-1"));
        OutputStream out = response.getOutputStream();
        wb.write(out);
//        wbxlsx.write(out);
        out.flush();
        out.close();

    }
    
    /**
     * @param wb 工作薄
     * @param imageMsg  图片的base64加密报文,这个由echarts 中的js 获取 app.getDataURL()
     * @throws Exception 
     * void  把页面传进来的 图片 画到excel 中去,这是xls版本,xlsx也差不多
     * 
     */
    public void drawImage(HSSFWorkbook wb,String imageMsg) throws Exception{
        HSSFSheet sheet = wb.getSheetAt(0);
        // 创建绘图
        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        BASE64Decoder base64Decoder = new BASE64Decoder();
        ByteArrayOutputStream dataChartStringoutStream = new ByteArrayOutputStream();
        ByteArrayInputStream dataChartStringin = new ByteArrayInputStream(base64Decoder.decodeBuffer(imageMsg.substring(22))); // 将picInfoByte作为输入流;
        BufferedImage dataChartStringbufferImg = ImageIO.read(dataChartStringin); // 将dataChartStringin作为输入流,读取图片存入image中
        ImageIO.write(dataChartStringbufferImg, "png", dataChartStringoutStream); // 利用HSSFPatriarch将图片写入EXCEL

        
//        HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2)
//        dx1 dy1 起始单元格中的x,y坐标.(一般设置为0即可)
//        dx2 dy2 结束单元格中的x,y坐标(一般设置为0即可)
//        col1,row1 指定起始的单元格,下标从0开始
//        col2,row2 指定结束的单元格 ,下标从0开始
        
        HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 22, 2, (short) 37, 16);
        anchor.setAnchorType(3);
        patriarch.createPicture(anchor, wb.addPicture(dataChartStringoutStream.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG));
    }
    
    /**
     * @param wb 工作薄
     * @param imageMsg  图片的base64加密报文,这个由echarts 中的js 获取 app.getDataURL()
     * @throws Exception 
     * void  把页面传进来的 图片 画到excel 中去,这是xls版本,xlsx也差不多
     * 
     */
    public void drawImage_xlsx(XSSFWorkbook wb,String imageMsg) throws Exception{
        XSSFSheet sheet = wb.getSheetAt(0);

        //去掉标识22位,解码
        byte[] img = Base64.decodeBase64(imageMsg.substring(22).getBytes());
        //在工作表中画图
        XSSFDrawing xssfDrawing = sheet.createDrawingPatriarch();
        //后四个参数是: 前两个表示 左上角 列号、行号,  右下角 列号、行号
        XSSFClientAnchor clientAnchor=new XSSFClientAnchor(0,0,0,0,22,2,37,16);
        //根据指定位置来画图
        xssfDrawing.createPicture(clientAnchor,wb.addPicture(img,XSSFWorkbook.PICTURE_TYPE_PNG));
    }
    
    /**
     * @param wb  工作薄
     * @param Hyddrb yjbb  实体类
     * @throws Exception 
     * void  根据实体类的值,实例化,excel表格中的 数据
     * 
     */
    public void initSheetCell(HSSFWorkbook wb, Hyddrb yjbb) throws Exception{
        //获取子表数据
        List<Hygxgdl> hygxgdlList = hyddrbService.getHygxgdlList(yjbb.getId());
        // 数据不够,凑空的进去,填格式
        hygxgdlList = hyddrbService.initGxgdl(hygxgdlList);
        
        HSSFSheet sheet = wb.getSheetAt(0);
        HSSFCell cell = null;
        // 数字或者字母组成,但是必须以字母开头
        String pattern = "([a-zA-z])+(\\d|[a-zA-Z])*";
        // 默认需要遍历excel 这么多行
        int initTotleNub = 30;
        // 预估要从excel插入的行数,比插入行数大就行,多个几十不成问题
        // 遍历每行
        for (int i = 1; i <= initTotleNub; i++) {
            // 遍历每列
            for (int j = 0; j <= 25; j++) {

                Row row = sheet.getRow(i);
                if (row != null) {
                    cell = (HSSFCell) row.getCell(j);
                    if (cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        String tmp = cell.getStringCellValue();
                        boolean isMatch = Pattern.matches(pattern, tmp);

                        if ("sbr".equals(tmp)) {
                            cell.setCellValue("值班人员:" + yjbb.getSbr());
                        } else if ("dw".equals(tmp)) {
                            if (hygxgdlList != null && hygxgdlList.size() != 0) {
                                // 产生空行
//                                ExportExcelUtil.excelInsertRow(wb, sheet, i, hygxgdlList.size() - 1);

                                // 给空行 赋给子表的值
                                for (int a = (i + 1); a <= i + hygxgdlList.size(); a++) {// 遍历每行
                                    Hygxgdl e = hygxgdlList.get(a - i - 1);
                                    Row userRow = sheet.getRow(a - 1);
                                    userRow.getCell(1).setCellValue(e.getDw());
                                    userRow.getCell(2).setCellValue(e.getWgdl());
                                    userRow.getCell(4).setCellValue(e.getSddl());
                                    userRow.getCell(6).setCellValue(e.getFddl());
                                    userRow.getCell(8).setCellValue(e.getGfdl());
                                    userRow.getCell(10).setCellValue(e.getDfdygdl());
                                    userRow.getCell(12).setCellValue(e.getSjgdl());
                                    userRow.getCell(14).setCellValue(e.getWgfh20());
                                    
                                    userRow.getCell(16).setCellValue(e.getZgwgfh());
                                    userRow.getCell(18).setCellValue(e.getPjwgfh());
                                    userRow.getCell(20).setCellValue(e.getWgfhl());
                                    
                                }
                            }
                        } else if (StringUtil.isNotEmpty(tmp) && isMatch&&!"MWH".equals(tmp)&&!"MW".equals(tmp)) {
                            this.setCellValTwo(yjbb, cell, tmp, wb);
                        }

                    }
                }
            }
        }
    }
    
    /**
     * @param wb  工作薄
     * @param Hyddrb yjbb  实体类
     * @throws Exception 
     * void  根据实体类的值,实例化,excel表格中的 数据
     * 
     */
    public void initSheetCell_xlsx(XSSFWorkbook wb, Hyddrb yjbb) throws Exception{
        //获取子表数据
        List<Hygxgdl> hygxgdlList = hyddrbService.getHygxgdlList(yjbb.getId());
        // 数据不够,凑空的进去,填格式
        hygxgdlList = hyddrbService.initGxgdl(hygxgdlList);
        
        XSSFSheet sheet = wb.getSheetAt(0);
        XSSFCell cell = null;
        // 数字或者字母组成,但是必须以字母开头
        String pattern = "([a-zA-z])+(\\d|[a-zA-Z])*";
        // 默认需要遍历excel 这么多行
        int initTotleNub = 30;
        // 预估要从excel插入的行数,比插入行数大就行,多个几十不成问题
        // 遍历每行
        for (int i = 1; i <= initTotleNub; i++) {
            // 遍历每列
            for (int j = 0; j <= 25; j++) {
                
                Row row = sheet.getRow(i);
                if (row != null) {
                    cell = (XSSFCell) row.getCell(j);
                    if (cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        String tmp = cell.getStringCellValue();
                        boolean isMatch = Pattern.matches(pattern, tmp);
                        
                        if ("sbr".equals(tmp)) {
                            cell.setCellValue("值班人员:" + yjbb.getSbr());
                        } else if ("dw".equals(tmp)) {
                            if (hygxgdlList != null && hygxgdlList.size() != 0) {
                                // 产生空行
//                                ExportExcelUtil.excelInsertRow(wb, sheet, i, hygxgdlList.size() - 1);
                                
                                // 给空行 赋给子表的值
                                for (int a = (i + 1); a <= i + hygxgdlList.size(); a++) {// 遍历每行
                                    Hygxgdl e = hygxgdlList.get(a - i - 1);
                                    Row userRow = sheet.getRow(a - 1);
                                    userRow.getCell(1).setCellValue(e.getDw());
                                    userRow.getCell(2).setCellValue(e.getWgdl());
                                    userRow.getCell(4).setCellValue(e.getSddl());
                                    userRow.getCell(6).setCellValue(e.getFddl());
                                    userRow.getCell(8).setCellValue(e.getGfdl());
                                    userRow.getCell(10).setCellValue(e.getDfdygdl());
                                    userRow.getCell(12).setCellValue(e.getSjgdl());
                                    userRow.getCell(14).setCellValue(e.getWgfh20());
                                    
                                    userRow.getCell(16).setCellValue(e.getZgwgfh());
                                    userRow.getCell(18).setCellValue(e.getPjwgfh());
                                    userRow.getCell(20).setCellValue(e.getWgfhl());
                                    
                                }
                            }
                        } else if (StringUtil.isNotEmpty(tmp) && isMatch&&!"MWH".equals(tmp)&&!"MW".equals(tmp)) {
                            this.setCellValTwo_xlsx(yjbb, cell, tmp, wb);
                        }
                        
                    }
                }
            }
        }
    }
    
    private void setCellValTwo(Hyddrb entity, HSSFCell cell, String tmp,HSSFWorkbook wb ) throws Exception {
        
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Method method = entity.getClass().getMethod("get" + StringUtil.makeFirstLetterUpperCase(tmp));
        Object o = method.invoke(entity);
        String val = null;
        if (o == null) {
            val = "";
        } else if (o instanceof String || o instanceof Long || o instanceof Integer || o instanceof Short) {
            val = method.invoke(entity) + "";
        } else if (o instanceof Double) {
            val = method.invoke(entity) + "";
            if (val.endsWith(".0")) {
                val = val.replace(".0", "");
            }
        } else if (o instanceof Date) {
            val = sdf.format((Date) method.invoke(entity));
        }
        cell.setCellValue(val);
        cell.getCellStyle().setWrapText(true);// 自动换行,没有效果
    }
    
    private void setCellValTwo_xlsx(Hyddrb entity, XSSFCell cell, String tmp,XSSFWorkbook wb ) throws Exception {
        
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Method method = entity.getClass().getMethod("get" + StringUtil.makeFirstLetterUpperCase(tmp));
        Object o = method.invoke(entity);
        String val = null;
        if (o == null) {
            val = "";
        } else if (o instanceof String || o instanceof Long || o instanceof Integer || o instanceof Short) {
            val = method.invoke(entity) + "";
        } else if (o instanceof Double) {
            val = method.invoke(entity) + "";
            if (val.endsWith(".0")) {
                val = val.replace(".0", "");
            }
        } else if (o instanceof Date) {
            val = sdf.format((Date) method.invoke(entity));
        }
        cell.setCellValue(val);
        cell.getCellStyle().setWrapText(true);// 自动换行,没有效果
    }

java代码
java

 

模板截图

 

 

 效果截图

 

 

相关说明:

其中excel是自己制作好的 导出模板,上面格子存有java实体类的属性名,读取excel后判断是那些属性,通过反射机制获取值在set到excel格子

echarts前端生成的图片base64加密报文,传到后台 java解密后,把它写进excel

 

遇到的问题A:

导出的图表仅仅是空的,没有数据

解决方案1:取消 图表里面动画效果,就是在 option 中添加一个  animation: false 属性 (这个方便,我就用这个)

解决方案2:延迟 相机的 拍照时间,即生成的图片要时间,可以使用setTimeout(function () {xxx}, 1000),延迟一下在获取

参考链接:https://blog.csdn.net/WWW_share8/article/details/103679701?spm=1001.2101.3001.4242.4&utm_relevant_index=8

 

遇到的问题B:

使用windows的open可以打开浏览器下载文件,但是异步的ajax不行

解决方案:使用jq直接生成一个隐藏的form表单,然后添加需要传参的控件,最后提交即可

 

posted @ 2022-08-25 10:31  爱跳舞的程序员  阅读(698)  评论(0编辑  收藏  举报