如何将html表转换为csv字符串

时间:2014-11-07 13:03:18

标签: javascript jquery

我有一张桌子,里面有thead,tfoot,tr,td和th。 td或th具有colspan或rowspan属性,如何将其转换为csv字符串,每个合并的单元格未合并为多个字段?

例如:

<table>
  <thead>
    <tr>
      <th>1</th>
      <th>2</th>
    </tr>
  </thead>
  <tr>
    <td rowspan='2'>3</td>
    <td>4</td>
  </tr>
  <tr>
    <td>5</td>
  </tr>
  <tfoot>
    <tr>
      <th colspan='2'>6 <span style='display:none'> 7 
</span> 8</th>
    </tr>
  </tfoot>
</table>

应输出:

"1","2"
"3","4"
"","5"
"6  7  8",""

除了table2CSV之外还有其他插件吗?因为这个显示tfoot在第一行而不是在最后一行,也合并显示为单个字段的单元格。

2 个答案:

答案 0 :(得分:1)

我已经制作了一个100%无jQuery的插件。

您可以立即将它与jQuery集成。

目标是尝试以最佳方式完成这项工作。

以下是代码:

(function(window,undefined){

    window.T2CSV=function(table){
        if(! (table instanceof window.HTMLTableElement))
        {
            throw new window.TypeError('A <table> element is required, instead '+table+' was passed');
        }

        var tr,thead,csv,tfoot,cols,prop=(table.innerText===undefined?'textContent':'innerText'),
            setVars=function(){
                var elements=table.getElementsByTagName('tr');

                if(elements.length<1)
                {
                    throw new window.RangeError('At least 1 <tr> element is required, you have 0 on your <table>.');
                }

                tr=Array.prototype.slice.call(elements,1);
                thead=elements[0];
                cols=thead.children.length;
                elements=null; //free memory
                csv='';

            },
            render={
                header:function(){
                    if(! (thead.children[0] instanceof window.HTMLTableCellElement))
                    {
                        throw new window.RangeError('At least 1 <tr> element with 1 <td> or <th> is required.');
                    }

                    for(var i=0,children=thead.children,l=children.length,csv=[];i<l;i++)
                    {
                        csv[csv.length]='"'+children[i][prop]+'"';
                    }
                    children=null; //free memory
                    return csv;
                },
                data:function(){

                    if(!tr.length)
                    {
                        return '';
                    }

                    for(var i=0,l=tr.length,csv=[],tfoot=false;i<l;i++)
                    {
                        if(!tfoot && tr[i].parentNode.tagName=='TFOOT')
                        {
                            tfoot=tr[i];
                            continue;
                        }
                        csv[csv.length]=render.row(tr[i]);
                    }

                    if(tfoot)
                    {
                        csv[csv.length]=render.row(tfoot);
                    }

                    return csv.join('\r\n');
                },
                row:function(tr){
                    var td=tr.getElementsByTagName('td');

                    if(!td.length)
                    {
                        td=tr.getElementsByTagName('th');
                    }

                    for(var i=0,tmp=[];i<cols;i++)
                    {
                        tmp[i]=td[i]?'"'+td[i][prop]+'"':'""';
                    }
                    return tmp+'';
                }
            };

        setVars();

        return {
            toString:function(){
                if(csv)
                {
                    return csv;
                }

                return csv = [render.header(),render.data()].join('\r\n');
            },
            valueOf:function(){return this.toString();},
            refresh:function(){
                setVars();
            }
        }

    }

})(function(){}.constructor('return this')());

这个:function(){}.constructor('return this')()是一个受JSFuck启发的漂亮技巧,它会随时返回 REAL window个对象 ! 点击此处查看来源:http://www.jsfuck.com/

它没有评论,但我很确定我正在做的事情很容易理解。

如果我错了,请发表评论,我会更容易理解。

用法很简单:只需传递一个表(表,其中没有jQuery或者会阻塞)并将其转换为字符串。

生成的csv被缓存,因此,多次访问非常快。

方法.refresh()将销毁该缓存。

这不是最有效的方法,但它有效。

由于显而易见的原因,输出会略有不同。

而不是:

"1","2"
"3","4"
"","5"
"6  7  8",""

它产生了这个:

"1","2"
"3","4"
"5",""
"6  7  8",""

代码可以轻松定制。

我正在考虑更新它并为分隔符和配置添加转义。

在此处查看:[{3}}


更新(2014年11月15日):

我做了一个改进的版本!

它现在逃避斜线和双引号。

我仍然没有添加对更多分隔符和文本引号的支持。

这是我的代码:

(function(window,undefined){
    window.T2CSV=function(table){
        if(!(table instanceof window.HTMLTableElement))
        {
            throw new window.TypeError('A <table> element is required, instead '+table+' was passed');
        }

        var tr,thead,cols,tfoot,csv={
                header:'',
                data:[],
                footer:'',
                string:''
            },
            prop=(table.innerText===undefined?'textContent':'innerText'),
            setVars=function(){
                var elements=table.getElementsByTagName('tr');

                if(elements.length<1)
                {
                    throw new window.RangeError('At least 1 <tr> element is required, you have 0 on your <table>.');
                }

                tr=Array.prototype.slice.call(elements,1);
                thead=elements[0];
                cols=thead.children.length;
                elements=null; //free memory
                csv={
                    header:'',
                    data:[],
                    footer:'',
                    string:''
                };
            },
            addSlashes=function(data){
                return data.replace(/([\\"])/g,'\\$1');
            },
            render={
                header:function(){
                    if(! (thead.children[0] instanceof window.HTMLTableCellElement))
                    {
                        throw new window.RangeError('At least 1 <tr> element with 1 <td> or <th> is required.');
                    }

                    for(var i=0,children=thead.children,l=children.length,tmp=[];i<l;i++)
                    {
                        tmp[tmp.length]='"'+addSlashes(children[i][prop])+'"';
                    }
                    children=null; //free memory
                    return csv.header=tmp;
                },
                data:function(){

                    if(!tr.length)
                    {
                        return '';
                    }

                    for(var i=0,l=tr.length,tmp=[],tfoot=false;i<l;i++)
                    {
                        if(!tfoot && tr[i].parentNode.tagName=='TFOOT')
                        {
                            tfoot=tr[i];
                            continue;
                        }
                        csv.data[tmp.length]=tmp[tmp.length]=render.row(tr[i]);
                    }

                    if(tfoot)
                    {
                        csv.footer=tmp[tmp.length]=render.row(tfoot);
                    }

                    return tmp.join('\r\n');
                },
                row:function(tr){
                    var td=tr.getElementsByTagName('td');

                    if(!td.length)
                    {
                        td=tr.getElementsByTagName('th');
                    }

                    for(var i=0,tmp=[];i<cols;i++)
                    {
                        tmp[i]=td[i]?'"'+addSlashes(td[i][prop])+'"':'""';
                    }
                    return tmp+'';
                }
            };

        setVars();

        return {
            toString:function(){
                if(csv.string)
                {
                    return csv.string;
                }

                return csv.string = [render.header(),render.data()].join('\r\n');
            },
            valueOf:function(){return this.toString();},
            refresh:function(){
                setVars();
            },
            getHeader:function(){
                return csv.header;
            },
            getFooter:function(){
                return csv.footer;
            },
            getRows:function(){
                return csv.data;
            },
            getRow:function(row){
                return csv.data[row>>0];
            }
        };

    }

})(function(){}.constructor('return this')());

您可以在此处查看它:http://jsfiddle.net/qw8ponhu/2/

答案 1 :(得分:0)

如果您没有使用IE,可以使用table2CSV&amp; JQuery的

$(document).ready(function() {

  $('table').each(function() {
    var $table = $(this);

    var $button = $("<button type='button'>");
    $button.text("Export to spreadsheet");
    $button.insertAfter($table);

    $button.click(function() {
      var csv = $table.table2CSV({delivery:'value'});
      window.location.href = 'data:text/csv;charset=UTF-8,'
                            + encodeURIComponent(csv);
    });
  });
})