用JS做了一个POI表头合并语句的生成器

最近的项目里面要用到POI,不得不说,这比我之前用到的PHPExcel的效率高太多了,本来是件很轻松的事情了。结果碰到的问题就是这个项目的部署限制非常多,不允许在项目目录下放置Excel模板文件,也不允许在数据库中使用BLOB字段存放模板。这样就导致需要手动的将现有的Excel文件的标头用POI语句写出来。

本来这个事情也不算是个很困难的问题,但是碰到一些特别复杂的多行标头,麻烦就来了……因为行特别多,合并单元格需要数来数去的很麻烦,这就让我萌生了想要自动化完成的想法。

还好,Excel自07版之后就是以XML文件为基础的,不再是以二进制文件为基础的了,这样就不需要借助一些第三方工具来读取二进制的配置,只需要把相关的XLSX模板转化为XML文件,然后对XML文件进行操作就好了。

演示在这里

具体的使用方式如下:


  1. 首先先把模板文件另存为Excel 07以上的格式,即XLSX格式。
  2. 将文件的后缀名改为RAR,例如原有的为01.xlsx,变更后即为01.rar。
  3. 用WinRAR或者其他压缩工具解包。得到一个文件夹。提取其中的xl/worksheets/sheet1.xml文件。(如果有多个标签页,应该是挨个编号的)
  4. 把内容拷贝到下面的文本框中,点生成语句,就会自动生成POI语句了。

源代码如下:

$().ready(function(){
            $("#submit").click(function(){
                if($("#input").val() == ""){
                    alert("请输入内容!");
                    return false;
                }
                //开始从XML文件中把列抓出来
                var str = $("#input").val();
                str = str.replace(/^[\s\S]+/,"");
                str = str.replace(/<\/mergeCells>[\s\S]+$/,"");
                str = str.replace(//,"");
                var mergeCells = str.split(",");
                //取出所有的合并行
                var printline = "";
                for(var cells in mergeCells){
                    if(mergeCells[cells].search(/:/) != "-1"){
                        //切出起始格和结束格
                        var linen = mergeCells[cells].split(":");
                        //切出起始行和结束行,取出字母作为竖轴
                        var colStart = linen[0].replace(/[0-9]+/,"");
                        var rowStart = linen[0].replace(/[A-Z]+/,"") - 1;
                        var colEnd = linen[1].replace(/[0-9]+/,"");
                        var rowEnd = linen[1].replace(/[A-Z]+/,"") - 1;
                        /**/
                        printline += "sheet.addMergedRegion(new Region("+rowStart+", (short) "+AAtoNum(colStart)+", "+rowEnd+", (short) "+AAtoNum(colEnd)+"));\n";
                    }
                }
                $("#result").val(printline);
                $("#result").show();
            });
        });
        //多行的字符转数字
        function AAtoNum(str){
            var length = str.length;
            var num = 0;
            //这段在IE下有兼容性问题
            /*for(var chars in str){
                num += AtoNum(str[chars])*(Math.pow(26,length-chars-1));
            }*/
            for(var chars = 0; chars < length; chars++){
                num += AtoNum(str[chars])*(Math.pow(26,length-chars-1));
            }
            return num-1;
        }
        //单行字符转数字
        function AtoNum(str){
            switch(str){
                case "A":
                    return 1;
                case "B":
                    return 2;
                case "C":
                    return 3;
                case "D":
                    return 4;
                case "E":
                    return 5;
                case "F":
                    return 6;
                case "G":
                    return 7;
                case "H":
                    return 8;
                case "I":
                    return 9;
                case "J":
                    return 10;
                case "K":
                    return 11;
                case "L":
                    return 12;
                case "M":
                    return 13;
                case "N":
                    return 14;
                case "O":
                    return 15;
                case "P":
                    return 16;
                case "Q":
                    return 17;
                case "R":
                    return 18;
                case "S":
                    return 19;
                case "T":
                    return 20;
                case "U":
                    return 21;
                case "V":
                    return 22;
                case "W":
                    return 23;
                case "X":
                    return 24;
                case "Y":
                    return 25;
                case "Z":
                    return 26;
            }
        }

评论

此博客中的热门博文

远程记录OpenWRT日志

用OpenWRT打造自动翻墙路由器(详解篇)

转一下关于Fuck的用法