如何将从SVG元素和csv文件生成的PNG图像导出到可下载的ZIP文件中

时间:2016-05-26 03:45:57

标签: javascript csv svg jszip

我正在将SVG导出为PNG图像。现在我想将此PNG图像和CSV文件下载到ZIP文件夹中。我使用JSZIP将两个文件压缩到ZIP文件夹中。现在我点击在ZIP下载的下载按钮上。下载的ZIP包含所需的CSV文件,但包含一个空白图像。如何在所需的ZIP文件夹中下载所需的图像?

我目前的代码是:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link href="../build/nv.d3.css" rel="stylesheet" type="text/css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js" charset="utf-8"></script>
    <script src="../build/nv.d3.js"></script>
    <script type="text/javascript" src="FileSaver.js"></script>  
    <script type="text/javascript" src="jszip.js"></script>

    <style>
        text {
            font: 12px sans-serif;
        }
        svg {
            display: block;
        }
        html, body, #chart1, svg {
            margin: 0px;
            padding: 0px;
            height: 100%;
            width: 100%;
        }

        .dashed {
            stroke-dasharray: 5,5;
        }
    </style>
     <script type="text/javascript">

    function download()
    {


img = new Image(),
        serializer = new XMLSerializer(),
        svgStr = serializer.serializeToString(document.getElementById('svg'));

    img.src = 'data:image/svg+xml;base64,'+window.btoa(svgStr);

    // You could also use the actual string without base64 encoding it:
    //img.src = "data:image/svg+xml;utf8," + svgStr;

    var canvas = document.createElement("canvas");

    var w=3000;
    var h=3000;

    canvas.width = w;
    canvas.height = h;
    canvas.getContext("2d").drawImage(img,0,0,w,h);

    var imgURL = canvas.toDataURL("image/png");


var CSV="ab";

var zip = new JSZip();

 zip.file("abc.csv", CSV);
 zip.file("img.png", imgURL);

content = zip.generate();
    location.href="data:application/zip;base64," + content;
    }

    </script>
</head>
<body >

<div id="chart1" width="100%" height='100%'></div>
<button onclick="download()">Download</button>

<script>


var data = [{"color":"#a215af","key":"products","values":[
    {"y":0,"x":0},
    {"y":0,"x":1},
    {"y":1,"x":2},
    {"y":6,"x":3},
    {"y":2,"x":4},
    {"y":0,"x":5},
    {"y":13,"x":6}]}] 

nv.addGraph(function() {
        chart = nv.models.lineChart()
            .options({
                transitionDuration: 300,
                useInteractiveGuideline: true
            })
        ;;

  var days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];

  chart.xAxis
    .rotateLabels(-45)
    .tickValues([0, 1, 2, 3, 4, 5, 6])
    .tickFormat(function(d){
      return days[d]
    });


 chart.yAxis
            .axisLabel('Voltage (v)')
            .tickFormat(function(d) {
                if (d == null) {
                    return 'N/A';
                }
                return d3.format(',.2f')(d);
            });


 d3.select('#chart1').append('svg')
            .datum(data)
            .attr("id","svg")
            .attr("height","1000")
            .attr("width","1000")
            .call(chart);

  nv.utils.windowResize(chart.update);

  return chart;
});



</script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

在您的情况下,您告诉JSZip图像的内容是字符串data:image/png;base64,iVBORw0K...。最简单的解决方案是删除data:image/png;base64,部分并使用base64: true

zip.file("img.png", imgURL.slice("data:image/png;base64,".length), {base64:true});

但是创建/解析base64字符串效率不高(我的代码也得到了一个3000x3000的灰色图像,但这是不相关的。)

您还可以使用Blob来避免base64操作(并使用JSZip v3来支持它):canvas.toBlob将png文件作为blob获取,URL.createObjectURL以生成url中间图像。

此解决方案的示例(我无法获得完美的图像,但您的问题,将图像放入zip文件中,已修复):

var canvas = document.createElement("canvas");
canvas.width = 1000;
canvas.height = 1000;
var ctx = canvas.getContext("2d");

var serializer = new XMLSerializer(),
    svgString = serializer.serializeToString(document.getElementById('svg'));

var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var url = URL.createObjectURL(svg); // <-- create a blob url for the svg image
var img = new Image();
img.onload = function() {
  // draw the svg to a canvas
  ctx.drawImage(img, 0, 0);
  URL.revokeObjectURL(url);
  canvas.toBlob(function (blob) { // <-- convert the canvas to a png (in a blob)

    var zip = new JSZip();
    zip.file("abc.csv", CSV);
    zip.file("img.png", blob); // <-- JSZip v3 accepts blob

    content = zip.generateAsync({type:"blob"}).then(function (blob) {
      saveAs(blob, "result.zip"); // <-- trigger the download
    }, function (e) {
      console.error(e)
    });
  }, "image/png");
};
img.src = url; // <-- load the blob url