jsPDF无法实现任何样式

38

我刚开始使用jsPDF,但是我无论如何都不能使任何CSS样式生效!我尝试了内联、内部和外部样式表,但都没有成功!我在另一个SO帖子中读到,由于它实际上是将内容打印到文件中,因此需要一个打印样式表,但这也没有起作用。

我有一个非常基本的页面,我只想让任何CSS样式与之配合使用:

JS:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="jspdf.js"></script>
<script type="text/javascript" src="./libs/FileSaver.js/FileSaver.js"></script>
<script type="text/javascript" src="./libs/Blob.js/BlobBuilder.js"></script>
<script type="text/javascript" src="jspdf.plugin.standard_fonts_metrics.js"></script> 
<script type="text/javascript" src="jspdf.plugin.split_text_to_size.js"></script>               
<script type="text/javascript" src="jspdf.plugin.from_html.js"></script>
<script>
    $(document).ready(function(){
        $('#dl').click(function(){
        var specialElementHandlers = {
            '#editor': function(element, renderer){
                return true;
            }
        };
        var doc = new jsPDF('landscape');
        doc.fromHTML($('body').get(0), 15, 15, {'width': 170,   'elementHandlers': specialElementHandlers});
        doc.output('save');
        });
    });
</script>

HTML:

HTML:

<body>
    <div id="dl">Download Maybe?</div>
    <div id="testcase">
        <h1>  
            We support special element handlers. Register them with jQuery-style 
        </h1>
    </div>
</body>

最后,外部样式表:

h1{
    color: red;
}
div{
    color: red;
}

我确信所有的内容都已正确包含,没有错误,我已经检查过了。是否有一些额外的函数需要调用才能使css工作?请告诉我!非常感谢!如果你有其他建议也欢迎提出!

编辑: 这是确切的网页:

<html>
    <head>
        <link rel="stylesheet" href="print.css" type="text/css" media="print"/>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script type="text/javascript" src="jspdf.js"></script>
        <script type="text/javascript" src="./libs/FileSaver.js/FileSaver.js"></script>
        <script type="text/javascript" src="./libs/Blob.js/BlobBuilder.js"></script>
        <script type="text/javascript" src="jspdf.plugin.standard_fonts_metrics.js"></script>
        <script type="text/javascript" src="jspdf.plugin.split_text_to_size.js"></script>               
        <script type="text/javascript" src="jspdf.plugin.from_html.js"></script>
        <script>
            $(document).ready(function(){
                $('#dl').click(function(){
                var specialElementHandlers = {
                    '#editor': function(element, renderer){
                        return true;
                    }
                };
                var doc = new jsPDF('landscape');
                doc.fromHTML($('body').get(0), 15, 15, {'width': 170,   'elementHandlers': specialElementHandlers});
                doc.output('save');
                });
            });
        </script>
    </head>
    <body>
        <div id="dl">Download Maybe?</div>
        <div id="testcase">
            <h1>  
                We support special element handlers. Register them with jQuery-style 
            </h1>
        </div>
    </body>
</html>

你的控制台有出现任何错误吗?比如说,你的所有资源是否都正确加载了?我问这个问题是因为在我的开发环境中,“//ajax.googleapis.com”会出现问题,而“h t t p : //ajax.googleapis.com”则不会。针对这一点,你能否告诉我更多关于你的开发堆栈的信息——例如,页面是如何渲染的,使用的是 WAMP、MAMP、RoRails 还是 Node?虽然我不确定这些信息是否太重要,但谁知道呢——我想看到这个问题得到解答。 - sdailey
一切都在加载中,这只是一个简单的 .html 文件。 - samuraiseoul
我认为我们需要你的所有代码,或者你可以将它上传到某个地方吗?因为当我使用你提供的代码时,样式工作得非常好。 - Jarno
添加了完整的网页,它几乎没有任何不同。 - samuraiseoul
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
29

我认为问题在于你使用了 media="print" 而不是 media="screen"。尝试创建两个分开的文件,一个用于打印,另一个用于屏幕:

<link rel="stylesheet" href="print.css" type="text/css" media="print"/>
<link rel="stylesheet" href="screen.css" type="text/css" media="screen"/>

屏幕样式表包含在浏览器中看到的页面样式,打印样式表包含在打印或将其保存为PDF时所需的页面样式。

编辑

我检查了jsPDF网站,但我认为他们不支持CSS。您可以尝试使用以下方法创建具有不同文本颜色的文档:

doc.setFontSize(22);
doc.setTextColor(255, 0, 0);
doc.text(20, 20, 'This is a title');

doc.setFontSize(16);
doc.setTextColor(0, 255, 0);
doc.text(20, 30, 'This is some normal sized text underneath.');

在你的脚本中,在var doc = new jsPDF('landscape');下方插入以下代码。


我认为他们不支持CSS,请查看我的更新答案。 - Jarno
11
如果我无法应用CSS,JSPDF对我来说是没有用的,你知道有哪些库可以让我拍摄DOM子集的图片或PDF吗?格式并不重要,只要我能通过ID捕捉到DOM的子元素即可! - samuraiseoul
@Samuraisoulification,不是在客户端,但是CasperJS可以在服务器端对页面上的特定元素进行截图(http://docs.casperjs.org/en/latest/modules/casper.html#captureselector)。 - Evan Plaice
4
你可以使用类似于 http://html2canvas.hertzen.com/ 的工具进行屏幕截图,然后打印出来。 - liftarn
我也想展示一些CSS,但是它没有生效,有找到任何解决方法吗?我也无法获取图像。 - Mohammad Faizan khan
显示剩余2条评论

7

您可以尝试使用这个选项,它使用jsPDF、html2canvas和html2pdf库。

从其README文件中:

包含这些文件:

<script src="jspdf.min.js"></script>
<script src="html2canvas.min.js"></script>
<script src="html2pdf.js"></script>

然后您可以通过运行以下命令生成PDF:

html2pdf($('body').get(0), {
   margin:       1,
   filename:     'myfile.pdf',
   image:        { type: 'jpeg', quality: 0.98 },
   html2canvas:  { dpi: 192, letterRendering: true },
   jsPDF:        { unit: 'in', format: 'letter', orientation: 'portrait' }
});

3
你可以使用jsPDF来捕获屏幕截图,但需要同时使用html2canvas。使用html2canvas将HTML转换为画布并抓取图像内容。使用jsPDF创建一个空白PDF,并将HTML图像内容添加到PDF中并保存:
html2canvas(*html*, {
  onrendered: function(canvas) {
    const contentDataURL = canvas.toDataURL('image/png')
    let pdf = new jsPDF()
    pdf.addImage(contentDataURL, 'JPEG', 20, 20)
    pdf.save('form.pdf')
  }
})
这将保留所有CSS,但质量会稍微降低(模糊)。

0

@samuraiseoul,我们可以使用domtoimage进行复杂的HTML渲染

private async generatePDF(elemToPrint: HTMLElement): Promise<void> {
 this.printSection = document.createElement('div');
 this.printSection.id = 'printSection';
 document.body.appendChild(this.printSection);
 const dataUrl = await domtoimage.toPng(elemToPrint, {width: elemToPrint.clientWidth, height: elemToPrint.clientHeight});
 const img = document.createElement('img');
 img.src = dataUrl;
 img.alt = 'The Image';
 this.printSection.appendChild(img);
 setTimeout(() => window.print(), 500); //Just give some time to render stuff while playing with @media print css stuff  
}

这里是使用CSS的代码

@media screen {
 #printSection { 
  display: none;
 }
}
@media print {
  #printSection , #printSection *{
   display: block; // We need the * because only if we display all the items inside the printSection to display as block. then only our mighty firefox will render the second page. :) Hey, that's a bug from FF.
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,