【问题标题】:Convert HTML page to PDF with CSS3 Support使用 CSS3 支持将 HTML 页面转换为 PDF
【发布时间】:2020-12-03 18:54:31
【问题描述】:

我正在做一个小项目,通过我在 Vue + Laravel 中构建的界面创建多个 CV(或简历),然后我可以将其导出为 PDF。

我在导出 PDF 时遇到了问题。 Laravel DOMPDF 不允许我在 PDF 中包含 CSS3 属性,例如 flex 或 CSS 变量。我相信 PDF 仅支持 CSS 2.0,但我看到导出的多个 PDF 是网站的精确副本。例如,resume.io - 当您通过他们的网站创建简历时,他们可以将其导出并使其看起来与网站版本完全相同。

我的问题是:有没有人知道我可以使用与 Vue 或 Laravel 相关联的库,它将网站模板的副本生成 PDF?

我尝试了一些 JS 库,它们对页面上的某些元素进行屏幕截图,然后尝试将它们组合在一起,但它不起作用。我基本上需要页面上的特定元素可供选择,然后保存为 PDF。请参阅下面的示例:

如您所见,白色区域是简历预览,所以我需要将整个部分保存为 PDF,减去右侧菜单和顶部栏。我正计划构建一些非常酷的模板,但如果我不能使用现代 CSS 实践,那么将它们制作成 PDF 将非常困难。

目前,我有两个视图,您可以在上面看到的 CV 预览,然后是另一个视图,它重新使用插入到 PDF 模板中的部分。显然,重用应用了现代 CSS 的部分会导致 PDF 损坏或看起来损坏。

我的堆栈:

  • Laravel
  • Vue.js
  • TailwindCSS
  • Laravel-DOMPDF

如果有人能就解决此问题的最佳方法提出建议,我将不胜感激。

TIA

【问题讨论】:

    标签: node.js laravel vue.js pdf


    【解决方案1】:

    由于您没有提到转换后的页面是在 Vue 或 Blade 中,所以我会解释两种方式。

    这里是Library,你只需要设计一个 Blade 视图,然后做这样的事情

    Route::get('/doc', function () {
    //
        $data = Marketers::all();
    
        // LoadView with $data
        $pdf = PDF::loadView('pdf',$data)->setPaper('A4');
    
        // LoadView with Compact
        $pdf = PDF::loadView('pdf',compact('data'))->setPaper('A4');
    
        // Then Download it
        return $pdf->download('pdf.pdf');
    });
    

    现在在 Vue 中,您需要 jsPDFhtmlToCanvashtmlToIMage

    我使用HTMLtoImage 是因为我在波斯语方面遇到了一些字符问题,所以我会根据HtmlToImage 库帮助您。

     <template>
            // Part you want to Convert to pdf or ...
            <div  ref="contentz" id="jsPdf" >
            // Contents
            <div/>
     </template>
    
    downloadFull(t) {
        let self = this
        switch (t) {
            case 1:
                const doc = new jsPDF("l", "mm", "a4");
                    htmlToImage.toCanvas(document.getElementById('jsPdf'))
                        .then(function (canvas) {
    
                            var img = canvas.toDataURL("image/jpeg");
                            var width = doc.internal.pageSize.getWidth();
                            var height = doc.internal.pageSize.getHeight();
                            doc.addImage(img, 'JPEG', 0, 0, width, 0);
                            doc.save('app.pdf');
    
    
                        })
                        .catch(function (error) {
                            self.$notifications.failedNotificationOnGetData(self)
                        });
                break;
            case 2:
                    htmlToImage.toJpeg(document.getElementById('jsPdf'), { quality: 1 })
                        .then(function (dataUrl) {
                            var link = document.createElement('a');
                            link.download = 'kalabala.jpeg';
                            link.href = dataUrl;
                            link.click();
                        })
                        .catch(function (error) {
                            self.$notifications.failedNotificationOnGetData(self)
                        });
                }
                break;
            default:
                break;
    
        }
    }
    

    所以这是我的函数 downloadFull(t) t 将是文件类型,你可能不需要它,或者你可以用简单的 if/else 来改进它而不用开关,首先你将导入像这样的库:

    import jsPDF from 'jspdf';
    import htmlToImage from 'html-to-image';
    

    然后为jsPDF设置页面尺寸,然后只需使用HtmlToImage获取Canvas,然后使用变量设置宽度、高度和图像Canvas,然后将图像添加到doc并保存。我的功能是相同的,但在第一个 switch case 我会得到PDF,第二个我会得到JPEG

    如果您尝试使用第一种方法但在 Vue 页面中获取下载链接,则您必须像我在上面解释的那样执行控制器,然后在 VUE 进行 API 调用时,您应该使用 BLOB 下载文件。这是示例:

    getPDF(type) {
        axios({
            url : '/api/api_name/exportPDF',
            method: 'POST',
            responseType: 'blob'
        })
            .then(res => {
    
                const url = window.URL.createObjectURL(new Blob([res.data]));
                const link = document.createElement('a');
                link.href = url;
                link.setAttribute('download', 'pdf.pdf');
                document.body.appendChild(link);
                link.click();
            })
    },
    

    祝你好运。

    【讨论】:

    • 感谢您的回答 Atlas,非常感谢。这也适用于多个页面吗?我目前正在尝试使用 Laravel Snappy。这是一个刀片模板,将用于转换为 PDF。
    • @Matt well ofc 它会起作用,但您必须意识到获得结果的逻辑是什么。如果您对此进行了测试并且有效,请标记答案,然后用另一个问题解释您想要什么以及您的逻辑是什么,以帮助您解决另一个主题。还有其他方法,但是,我试图在这个答案中解释你可以通过这 3 种方法获得的最简单/合法的答案。
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    • 2014-07-09
    • 2015-03-02
    • 2020-04-03
    • 2019-08-04
    相关资源
    最近更新 更多