zoukankan      html  css  js  c++  java
  • Jxl、JxCell图表导出功能的实现

    最近接触过许多报表导出功能,也用过多种工具进行导出功能的实现,但对于图表的导出一直没有仔细的去展开研究和探讨,直到最近略微整理了下这方面的需求和技术攻克。

    首先导出excel功能的实现主要有JXL、JXCELL、POI等工具。目前只实现了JXL和JXCELL。

    JXL:

      先介绍下JXL:

      jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI。其中功能相对POI比较弱一点。但jExcelAPI对中文支持非常好,API是纯Java的, 并不 依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。 另外需要说明的是,这套API对图形和图表的支持很有限,而且 仅仅识别PNG格式。

      通过过jxl导出EXCEL报表,相信很多同行已经实现,并且网上有大量的例子和文章来介绍他,这里就不在记录。

      本文着重介绍如果你使用了JXL进行EXCEL的导出,并且暂时无法替换工具(这里说的是整体替换),同时又有新的需求对已有的图表进行导出(之前导出报表),那么下面的方法将会帮助到您:

      首先JXL对于EXCEL图表的导出能力有限,在本人进行大量的资料查询后仍没有具体的办法。但是请注意,在JXL介绍当中提到,JXL对图形和图表有支持,虽然仅仅识别PNG格式的图片,但却也同时提供了一种方法:

      思路:

        页面展示图表所用到的JS框架,都有提供对图表FLASH 进行格式的转化,转化为图片。如:Open Flash Chart。

        在Open Flash Chart中,通过javascript把flash保存成图片。运用js就可以直接在页面生产图片jQuery 的实现:
        

    1 <script src="Resources/swfobject.js" type="text/javascript"></script>
    2 
    3 <script type="text/javascript">
    4     swfobject.embedSWF("Resources/open-flash-chart.swf", "divChange", "550", "300",
    5                              "9.0.0", "expressInstall.swf",
    6                              { "data-file": "OpenFlashChartData/LineData.aspx" }
    7             );
    8 </script>

      Html页面:

    <div id="divChange">
    </div>
    <input type="button" name="btncopy" onclick="OFC.jquery.rasterize('divChange', 'img_chart_1')"
        value="生成图片" />
    <div id="img_chart_1">
    </div>
    

      Js代码如下:

    <script type="text/javascript">
        OFC = {};
        OFC.jquery = {
            name: "jQuery",
            version: function(src) { return $('#' + src)[0].get_version() },
            rasterize: function(src, dst) { $('#' + dst).replaceWith(OFC.jquery.image(src)) },
            image: function(src) { return "<img src='data:image/png;base64," + $('#' + src)[0].get_img_binary() + "' />" },
            popup: function(src) {
                var img_win = window.open('', 'Image')
                with (img_win.document) {
                    write('<html><head><title>Tipsdoo Chart Report Image</title></head><body>' + OFC.jquery.image(src) + '</body></html>')
                }
                img_win.document.close();
            }
        }
    
        if (typeof (Control == "undefined")) { var Control = { OFC: OFC.jquery} }
    
        function save_image() { OFC.jquery.popup('divChange') }
        function moo() { alert(99); };  
    </script>
    

      页面运行情况:

      (本例网上资料)

      这样就把FLASH格式的图表转化为了 PNG格式的图片,并且是BASE64编码的图片资源(html识别,并且能够显示)。

      在获取到PNG图片时,通过AJAX 把BASE64编码格式的图片传到后台:

      

    function save_image() {
           var pic1;
           var pic2;
           $.ajax({
               type : "POST",
               url : "xxxx.do?method=xxx",
               dataType : "json",
               async : false,
               data:{imgstr:$('#图片所在标签ID')[0].get_img_binary(),imgstr1:$('#图片所在标签ID')[0].get_img_binary()},
               error : function(XMLHttpRequest, textStatus, errorThrown) {
                   alert("error");
               },
               success : function(data, textStatus) {
                   if (data && data.result != "") {
                       pic1 = data.result.split('%')[0];
                       pic2 = data.result.split('%')[1];
                       exportFilter(pic1,pic2);//导出方法
                   }
               }
           });
        }

      exportFilter(pic1,pic2):

      

    function exportFilter(pic1,pic2) {
            OFC.jquery.rasterize('图表所在标签ID', '图片所在标签ID');
            OFC.jquery.rasterize('图表所在标签ID', '图片所在标签ID');
            submitFrm(document.getElementById("myOneForm"),
                    "xxxxxxxx.do?method=xxxxxx&pic1="+pic1+"&pic2="+pic2);
    }

      这样 通过AJAX 把图片传回 后台,后台做相应的处理,保存图片文件到服务器上,并且返回图片的名称(BASE64格式转码保存为文件可以网上找到资料)。

      然后再发送导出EXCEL文件请求,到了这一步则是后台处理数据集合通过JXL编辑EXCEL 插入数据。然后就是JXL插入图片代码:

      

     1     File imgFile1 = new File("D:/"+userId+"/"+pic1+".png");
     2             File imgFile2 = new File("D:/"+userId+"/"+pic2+".png");
     3             WritableImage img1 = new WritableImage(7, 0, 7, 18, imgFile1);  
     4             WritableImage img2 = new WritableImage(7, 19, 7, 18, imgFile2);  
     5             sheet.addImage(img1);
     6             sheet.addImage(img2);
     7             
     8             // 写入excel
     9             pWorkbook.write();
    10             pWorkbook.close();

       这里是取到之前保存的图表PNG格式的图片,然后通过JXL自带的图片插入方法插入到EXCEL中,位置可以自定。

       这样就可以实现JXL 图表、报表的同时导出,

         优点:1、导出的是原生页面显示图表,并且在EXCEL可以随意的拖动 ,改变图片的大小。2、能够满足各种图表,甚至是非规则图表、甚至可以导出任意大小小于

    2M的图片

       缺点:1、必须先把需要的图表展现在页面上,然后才能保证报表,图表数据的一致性。2、实现麻烦,需要把先保存图片到后台。3、转码过程中容易出现图片损坏。

        提醒:为了不浪费服务器性能,图片需要放在临时文件夹中,定时删除或者导出完立即删除。

    JXCELL:

      JXCELL对图表的导出支持很突出。因为支持了EXCEL自带的绘制图表的方法。因此并不依赖于页面JS图表框架,只要有数据源。

      下面一个小的例子:

      基本的报表导出就不多做介绍。看代码,插入饼图:

      

     1 ChartShape chartpie = m_view.addChart(0, 25 + count, 5, 37 + count);
     2         chartpie.setTitle("图表的名称");
     3         chartpie.setChartType(ChartShape.TypePie);//图表类型
     4 
     5         chartpie.addSeries();
     6         chartpie.setSeriesYValueFormula(0, name + "!$B$25:$B$" + (24 + count));\饼图数据源,饼图需要的具体数字,不包含总数,参数为 开始单元格结束单元格,EXCEL提供
     7         chartpie.setCategoryFormula(name + "!$A$25:$A$" + (24 + count));//数据对应的说明.如:货车  12辆,这里是货车
     8         chartpie.setVaryColors(true);
     9         this.getChartShapeAttribute(chartpie, 1);
    10         chartpie.setLegendPosition(ChartFormat.LegendPlacementRight);

      很简单的就插入到了EXCEL当中。下面附上JXCELL  API 网站:

      http://www.jxcell.net/

      优点:简单快捷,数据同步。与页面图表无关系。

      缺点:EXCEL自带的图表样式,如果EXCEL不支持,则JXLCELL也无能为力

     

    总结:

      总体来说 JXCELL 优先级比较高,因为实现方便,但是对于复杂的图表则相对乏力,因为前台JS图表框架的发展迅猛,越来越多样式的图表展现在页面上,如地图类的

    图表,EXCEL本省不能生成这些图表,这时候JXL则能够实现。POI据说实力强大,但本人没有去研究,故在此不做介绍。也希望熟悉POI的同僚能够反馈给我,在此加以补充

      本人初涉博客,目的方面自己方便大家,大家在发现博客有误时,还请能够反馈给我,在这小弟不胜感激,有来有往共同成就未来!

    /*********************补充****************************/

      从发此篇随笔至今 也过去好久了,在此对此篇文章作出补充

      前面提到了对图表的导出一些常用的工具.

      在对于jxcell 工具 操作excel对图表进行导出时,犹豫jxcell api的不完善,方法的缺失?  或者属性方法的混乱,导致

    在对excel操作图标时 往往不能绘制出想要的图表,

      再进一步的方法就是,利用模板实现导出功能,报表的导出 相信大家都有好几种方法好几种工具,其中就有一个利用模板导出,在模板

    excel当中编写函数 使之实现大量数据的导出。不仅如此图表也可以实现,在模板excel当中选择合适的类型的图表(这比jxcel提供的图表类型可多得太多),

    然后设置图表的动态数据源来实现图表的导出。同样缺点明显,类型满足,但样式美观差强人意,远远不如前端框架画出来的图标好看。

      目前上班中,至此先补充方法,晚上 会补充具体的实现方法和实例代码。

      

  • 相关阅读:
    springboot下使用多线程
    springboot 下测试 service中的方法
    maven 将本地jar包 安装到本地仓库
    idea下http响应乱码
    使用vue-element-admin框架时如何添加多级目录
    如何在uniapp中使用mqtt
    在uniapp设计的APP中引入axios,支持cookie(真机亲测可行)
    vue中get方法如何传递数组参数
    Vue跨域访问,axios&cors
    Vue页面间传值,客户端数据存储,以及父子组件间props传值
  • 原文地址:https://www.cnblogs.com/sicd/p/3895628.html
Copyright © 2011-2022 走看看