将画布转换为 PDF

IT技术 javascript canvas pdf-generation
2021-02-11 06:06:14

是否可以使用 JavaScript(pdf.js或类似的东西)直接将画布转换为 pdf

有没有另一种可能的方式,比如画布到 img 然后 img 到 pdf?

你能举个例子吗?

4个回答

您可以通过利用jsPDF库和toDataURL函数来实现这一点

我做了一个小示范:

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

// draw a blue cloud
context.beginPath();
context.moveTo(170, 80);
context.bezierCurveTo(130, 100, 130, 150, 230, 150);
context.bezierCurveTo(250, 180, 320, 180, 340, 150);
context.bezierCurveTo(420, 150, 420, 120, 390, 100);
context.bezierCurveTo(430, 40, 370, 30, 340, 50);
context.bezierCurveTo(320, 5, 250, 20, 250, 50);
context.bezierCurveTo(200, 5, 150, 20, 170, 80);
context.closePath();
context.lineWidth = 5;
context.fillStyle = '#8ED6FF';
context.fill();
context.strokeStyle = '#0000ff';
context.stroke();

download.addEventListener("click", function() {
  // only jpeg is supported by jsPDF
  var imgData = canvas.toDataURL("image/jpeg", 1.0);
  var pdf = new jsPDF();

  pdf.addImage(imgData, 'JPEG', 0, 0);
  pdf.save("download.pdf");
}, false);
<script src="//cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>


<canvas id="myCanvas" width="578" height="200"></canvas>
<button id="download">download</button>

嗯...尝试过,但 addImage 行返回错误...我认为该函数可能已被替换?
2021-03-19 06:06:14
这是可能的,但您必须编辑 jsPDF 库才能做到这一点。
2021-03-21 06:06:14
很好,谢谢:) 有什么方法可以导出与 img 相同大小(宽度/高度)的 pdf 吗?
2021-03-26 06:06:14
@Adil Waqar 您是否将 jspdf.js 文件添加为脚本?
2021-03-26 06:06:14
@MateuszBartkowski 我认为这是一个错误。当有人编辑我的答案以获得代码片段时添加了它。
2021-04-11 06:06:14

请参阅https://github.com/joshua-gould/canvas2pdf该库创建画布元素的 PDF 表示,与其他建议的将图像嵌入 PDF 文档的解决方案不同。

//Create a new PDF canvas context.
var ctx = new canvas2pdf.Context(blobStream());

//draw your canvas like you would normally
ctx.fillStyle='yellow';
ctx.fillRect(100,100,100,100);
// more canvas drawing, etc...

//convert your PDF to a Blob and save to file
ctx.stream.on('finish', function () {
    var blob = ctx.stream.toBlob('application/pdf');
    saveAs(blob, 'example.pdf', true);
});
ctx.end();
添加了对图像的支持。请参阅joshua-gould.github.io/canvas2pdf/demo.html 中的图像示例
2021-03-21 06:06:14
可惜它不支持上下文转换,即 ctx.setTransform(2,1,0.5,1,0,1); 图像看起来一样
2021-03-29 06:06:14
好的库,但不支持 drawmage() 所以你不能在 PDF 上添加位图图像
2021-04-01 06:06:14
多层画布怎么样?
2021-04-02 06:06:14
由于这个库不是简单地将画布渲染为 jpeg 并将其放入 PDF 中,因此它创建了高质量/高分辨率的 pdf
2021-04-05 06:06:14

所以今天,jspdf-1.5.3回答使 pdf 文件页面与画布完全相同的问题。经过多次不同组合的尝试,我想你必须做这样的事情。我们首先需要以正确的方向设置输出pdf文件的高度和宽度,否则侧面可能会被切断。然后我们从“pdf”文件本身获取尺寸,如果您尝试使用画布的尺寸,则侧面可能会再次被切断。我不确定为什么会发生这种情况,我最好的猜测是 jsPDF 转换库中其他单位的尺寸。

  // Download button
  $("#download-image").on('click', function () {
    let width = __CANVAS.width; 
    let height = __CANVAS.height;

    //set the orientation
    if(width > height){
      pdf = new jsPDF('l', 'px', [width, height]);
    }
    else{
      pdf = new jsPDF('p', 'px', [height, width]);
    }
    //then we get the dimensions from the 'pdf' file itself
    width = pdf.internal.pageSize.getWidth();
    height = pdf.internal.pageSize.getHeight();
    pdf.addImage(__CANVAS, 'PNG', 0, 0,width,height);
    pdf.save("download.pdf");
  });

从这里了解切换方向:https : //github.com/MrRio/jsPDF/issues/476

非常棒,非常感谢!
2021-03-20 06:06:14
谢谢,你的回答很有帮助。
2021-03-23 06:06:14

更好的解决方案是使用 Kendo ui draw dom 导出为 pdf-

假设以下 html 文件包含 canvas 标签:

<script src="http://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>

    <script type="x/kendo-template" id="page-template">
     <div class="page-template">
            <div class="header">
              
            </div>
            <div class="footer" style="text-align: center">
               
                <h2> #:pageNum# </h2>
            </div>
      </div>
    </script>
    <canvas id="myCanvas" width="500" height="500"></canvas>
    <button onclick="ExportPdf()">download</button>

现在,在您的脚本中写下以下内容,它将完成:

function ExportPdf(){ 
kendo.drawing
    .drawDOM("#myCanvas", 
    { 
        forcePageBreak: ".page-break", 
        paperSize: "A4",
        margin: { top: "1cm", bottom: "1cm" },
        scale: 0.8,
        height: 500, 
        template: $("#page-template").html(),
        keepTogether: ".prevent-split"
    })
        .then(function(group){
        kendo.drawing.pdf.saveAs(group, "Exported_Itinerary.pdf")
    });
}

就是这样,在画布上写下任何东西,然后只需按下所有导出为 PDF 的下载按钮。这是 Kendo UI 的链接 - http://docs.telerik.com/kendo-ui/framework/drawing/drawing-dom

很酷,但太贵了
2021-03-25 06:06:14