当前用于将html + svg + css转换为pdf的库

时间:2019-03-06 02:08:50

标签: javascript php html css svg

虽然存在多个此类问题,这是一个常见问题,但我想以更好的结果更新最新的库。

我有一些svg的html代码(一个div的内容),并使用了包含在html标头中的外部css和js。我正在寻找如何将其导出为pdf,它可以使用PHP或javascript。

尝试这些替代方法,但效果不佳:

  • jspdf(javascript):结果是pdf(较重),只有一页,质量低。
  • Html2Pdf(php):不支持svg标记。

  • mPDF(php):mpdf \ classes \ svg.php中的转换错误

您还建议其他哪些选择?

感谢您的贡献。

[编辑03-06]

为了继续使用mpdf,我尝试将svg标记转换为img。使用两种不同类型的图形,我可以做到高质量。

在第三,它不生成图像。一些代码可以了解所使用的方法:

HTML

<span id="graf_capitanias_ct"></span>

D3图形生成

<script type="text/javascript">
var margin = {top: 20, right: 160, bottom: 35, left: 30};
var width = 300 - margin.left - margin.right,
    height = 150 - margin.top - margin.bottom;

var svg = d3.select("#graf_capitanias_ct")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

/* Data in strings like it would be if imported from a csv */
var data = [
    { year: "2018", ct: "4", capitanias: "2"},
    { year: "2017", ct: "1", capitanias: "1"},
    { year: "2016", ct: "3", capitanias: "0"},
];

var parse = d3.time.format("%Y").parse;

// Transpose the data into layers
var dataset = d3.layout.stack()(["ct", "capitanias"].map(function(valor) {
  return data.map(function(d) {
    return {x: parse(d.year), y: +d[valor]};
  });
}));

// Set x, y and colors
var x = d3.scale.ordinal()
  .domain(dataset[0].map(function(d) { return d.x; }))
  .rangeRoundBands([10, width-10], 0.02);

var y = d3.scale.linear()
  .domain([0, d3.max(dataset, function(d) {  return d3.max(d, function(d) { return d.y0 + d.y; });  })])
  .range([height, 0]);

var colors = ["#d25c4d", "#f2b447"];

// Define and draw axes
var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .tickFormat(d3.format(",d"))
  .tickSize(-width, 0, 0)

var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom")
  .tickFormat(d3.time.format("%Y"));

svg.append("g")
  .attr("class", "y cap_ct_axis")
  .call(yAxis);

svg.append("g")
  .attr("class", "x cap_ct_axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)
  .selectAll("text")    
    .style("text-anchor", "end")
    .attr("dx", "-.8em")
    .attr("dy", ".15em")
    .attr("transform", "rotate(-65)");

// Create groups for each series, rects for each segment 
var groups = svg.selectAll("g.cost")
  .data(dataset)
  .enter().append("g")
  .attr("class", "cost")
  .style("fill", function(d, i) { return colors[i]; });

var rect = groups.selectAll("rect")
  .data(function(d) { return d; })
  .enter()
  .append("rect")
  .attr("x", function(d) { return x(d.x); })
  .attr("y", function(d) { return y(d.y0 + d.y); })
  .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
  .attr("width", x.rangeBand())
  .on("mouseover", function() { tooltip.style("display", null); })
  .on("mouseout", function() { tooltip.style("display", "none"); })
  .on("mousemove", function(d) {
    var xPosition = d3.mouse(this)[0] - 15;
    var yPosition = d3.mouse(this)[1] - 25;
    tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
    tooltip.select("text").text(d.y);
  });

 // Draw legend
var legend = svg.selectAll(".legend")
  .data(colors)
  .enter().append("g")
  .attr("class", "legend")
  .attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; });

legend.append("rect")
  .attr("x", width - 18)
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", function(d, i) {return colors.slice().reverse()[i];});

legend.append("text")
  .attr("x", width + 5)
  .attr("y", 9)
  .attr("dy", ".35em")
  .style("text-anchor", "start")
  .text(function(d, i) { 
    switch (i) {
      case 0: return "Capitan\u00edas";
      case 1: return "Cuerpos t\u00e9cnicos";
    }
  });

// Prep the tooltip bits, initial display is hidden
var tooltip = svg.append("g")
  .attr("class", "tooltip")
  .style("display", "none");

tooltip.append("rect")
  .attr("width", 30)
  .attr("height", 20)
  .attr("fill", "white")
  .style("opacity", 0.5);

tooltip.append("text")
  .attr("x", 15)
  .attr("dy", "1.2em")
  .style("text-anchor", "middle")
  .attr("font-size", "12px")
  .attr("font-weight", "bold");
</script>   

将svg转换为img

<script type="text/javascript">
function convierte_graficos_cap_ct() {
    var html = '';
    var imgscr = '';
    var img = '';
    var attributes = '';

    // css manual
    d3.selectAll('#graf_capitanias_ct svg')
    .style({
        "font": "10px sans-serif",
        "shape-rendering": "crispEdges"
    });
    d3.selectAll('.cap_ct_axis path, .cap_ct_axis line')
    .style({
        "fill": "none",
        "stroke": "#000"
    });
    d3.selectAll('.cap_ct_axis path.domain')
    .style({
        "stroke": "none"
    });
    d3.selectAll('.cap_ct_axis.y .tick line')
    .style({
        "stroke": "#ddd"
    });

    html = $('#graf_capitanias_ct').html();
    imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
    img = '<img src="'+imgsrc+'"';
    attributes = $('svg').prop("attributes");
    $.each(attributes, function() {
        img += ' '+this.name+'="'+this.value+'"';
    });
    img += '>';

    $('#graf_capitanias_ct').html(img); 
}
</script>

请注意,必须在重新转换之前添加css样式。最初是从外部CSS获取它们的。

因此,标记img显示“破损”不会转换svg。由于图表中有UTF-8文字(图例),因此中断。转换前应如何更改该文本? 谢谢

1 个答案:

答案 0 :(得分:0)

对于PDF生成,我们目前使用Snappy,它是WKHTMLTOPDF的包装。
我们将SVG用于嵌入到HTML中的图表并进行渲染。
尽管我们确实在尺寸和位置上存在一些问题。
我们最终将SVG转换为图像,然后将其编码为base64。
然后只需将Base64添加到<img src="[Base64String]">

Composer可以很好地消除这些依赖关系。

{ "require":{ "knplabs/knp-snappy": "^0.4.3", "h4cc/wkhtmltopdf-amd64": "0.12.x", "h4cc/wkhtmltoimage-amd64": "0.12.x", "h4cc/wkhtmltopdf-i386": "0.12.x", "h4cc/wkhtmltoimage-i386": "0.12.x", "wemersonjanuario/wkhtmltopdf-windows": "0.12.x" } }

其他一些选择是:

  • FPDF-FPDF是一个PHP类,它允许使用纯PHP生成PDF文件,也​​就是说,无需使用PDFlib库。 FPDF中的F表示免费:您可以将其用于任何用途,并对其进行修改以适合您的需求。
  • mPDF-mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。它基于FPDF和HTML2FPDF,具有许多增强功能。
  • dompdf-dompdf是HTML到PDF的转换器。 dompdf的本质是(大多数)PHP兼容的CSS 2.1 HTML布局和呈现引擎。它是样式驱动的渲染器:它将下载和读取外部样式表,内联样式标签以及单个HTML元素的样式属性。它还支持大多数演示HTML属性。
  • TCPDF-TCPDF是一个PHP库,可轻松并几行快速生成PDF文档。在创建PDF文件时,它支持自定义和许多关键功能。