CSS与DOMPDF不兼容

14

我正在使用DOMPDF(v 0.5.2)将html页面转换成pdf文件。

PHP脚本运行后,pdf文件出现了(如预期),但是所有内容都没有应用样式。据我所知,float属性在DOMPDF中无法工作,因此我必须做一些工作来解决这个问题,但是甚至字体样式也没有被应用。

我已经尝试了包括样式的三种方法:

1. 附加样式表,

<link href="styles.css" rel="stylesheet" type="text/css">

标题中的写作风格,

<style>...</style>

和内联样式。

<div class="..." style="...">

创建PDF的PHP文件如下所示...

<?php 
ob_start(); 
?>
<html>
<head>

<link href="flhaha.css" rel="stylesheet" type="text/css">

</head>

<body>
... content (divs, etc) 
</body>
</html>
<?php 
require_once("../../scripts/dompdf/dompdf_config.inc.php"); 
$dompdf = new DOMPDF(); 
$dompdf->load_html(ob_get_clean()); 
$dompdf->render(); 
$dompdf->stream('test.pdf');
?>

在内容中有一张图片,当pdf文件打开时可以正常加载并显示,但没有样式。

先行致谢!

编辑 #1:上面的标签应该是“style”,而不是“styles”。已更正此拼写错误。


你提供的示例链接对我来说无法使用。我看不出为什么样式不会被应用。你有收到任何PHP错误或通知吗?你能发布一些HTML+CSS的示例吗? - BrianS
@BrianS,服务器(bluehost)今天宕机了。现在已经恢复正常,链接也可以正常使用。非常抱歉! - Michael
一段时间后我意识到可能是你的主机出了问题。最终我还是得到了访问权限。 - BrianS
4个回答

5

dompdf v0.5.x不支持浮动。v0.6.0支持,但这仍然是一个实验性功能,必须在配置中启用。经过测试,我可以说dompdf处理不好它。如果您想坚持使用dompdf,您可以考虑使用表格,因为您的文档在某种程度上是表格化的。


我同意应该使用表格。我一直更喜欢divs,但改变它也没什么大不了的。你提到“坚持使用dompdf”,还有其他可以通过php代码编写pdf的工具吗?dompdf似乎是最流行的选择,所以我就选择了它。 - Michael
有许多基于PHP的库可供使用:mPDF,TCPDF,html2pdf。如果您想要更强大的功能,可以选择一个无头浏览器可执行文件,例如PhantomJS。 - BrianS
1
我最终选择了mPDF,效果非常好!CSS支持更好,易于使用。需要注意的一点是(对于将来引用此线程的人),“float”样式在mPDF中与<span>标签不兼容(只与<div>标签一起使用)。DOMPDF无法工作的原因是我的CSS是写成“.page”而不是“div.page”,但仍然只解决了部分问题。 mPDF获胜。感谢您的回答! - Michael
很遗憾看到你离开(我是其中一名开发人员)。但是……我完全理解。在某些用例中,其他库现在工作得更好。 - BrianS
@Michael,这对我也起作用了。我从dompdf转到了mPDF。 - Krish

4

内部样式表可通过在<style>元素中包含样式而不是<styles>元素来创建。

以下语句是错误的:

<styles>...</styles>

应该是:

<style> ... </style>

内联样式应按如下所示给出:

<div class="className" style="color:red;text-align: left;">

外部样式表应该按照下面所示的方式包含:
<link rel="stylesheet" type="text/css" media="screen" href="styles.css" />

如果外部样式表无法工作,请检查源文件路径。


"media = all" 可能是您想要的选择,因为PDF文件通常需要打印。 - mbomb007

2
简单的解决方案是,将你的CSS放在一个独立的(.php)或其他服务器脚本文件中,并将其包含在你的PDF文件中。 例如, 你有一个名为pdf.blade.php的PDF文件。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    {{-- <link rel="icon" href="/favicon.ico"> --}}

    <title>Starter Template for Bootstrap</title>
<style type="text/css">
@include('pdf.style')
</style>
  </head>
  <body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Project name</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">

      <div class="starter-template">
        <h1>Bootstrap starter template</h1>
        <p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
      </div>

    </div><!-- /.container -->
  </body>
</html>

假设您有一个名为style.css的CSS文件,那么接下来的步骤是复制你的CSS文件内容并将其粘贴到新的style.blade.php中。然后,您几乎就完成了!
现在将它包含在您的pdf文件中,例如:

<style>
  @include('style')
</style>    

这是我用过的简单技巧。


0
当我在本地运行时,如果样式包含在头部中,我可以应用样式。例如,在html.html中。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style>

@font-face {
  font-family: 'DanielBlack';
  src:  url('https://mywebsite/path/to//fonts/daniel-black-webfont.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
}

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: normal;
  src: url(http://themes.googleusercontent.com/static/fonts/opensans/v8/cJZKeOuBrn4kERxqtaUH3aCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
}

* {
  font-family: "Open Sans";
}

.daniel {
  font-family: "DanielBlack";
}

.size3 {
  font-size: 3rem;
}
        
h3 {
  color: red;
  font-family: DanielBlack;
}
</style>

</head>
<body>
  

<h1 class="daniel">h1 with daniel class</h1>
<h1>h1 with no class</h1>

<h2 class="daniel">h2 with daniel class</h2>
<h2>h2 with no class</h2>

<h3 class="daniel">h3 with daniel class</h3>
<h3 class="daniel size3">h3 with daniel and size3 class</h3>
<h3 class="size3">h3 with size3 class</h3>
<h3>h3 with no class</h3>

<span class="daniel">span with daniel class</span>
<span>span with no class</span>

<p class="daniel">p with daniel class</p>
<p>p with no class</p>

Some text no tag
</body>
</html>

然后在index.php中。
<?php
require 'vendor/autoload.php';

// reference the Dompdf namespace
use Dompdf\Dompdf;
use Dompdf\Options;

//load html
$html = file_get_contents('./html.html');

// add options
$options = new Options();
// $options->set('defaultFont', 'Daniel Black');
$options->set( 'isRemoteEnabled', true);
$options->set( 'setTempDir', '/tmp');
$options->set( 'setFontCache', '/tmp');
$options->set( 'setFontDir', '/tmp');
$options->set( 'setLogOutputFile', '/tmp');
$options->set( 'setIsFontSubsettingEnabled', true);

// instantiate and use the dompdf class
$dompdf = new Dompdf($options);

$dompdf->loadHtml($html);

// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');

// Render the HTML as PDF
$dompdf->render();

// Output the generated PDF to Browser
$dompdf->stream();

?>

关键要注意的是@font-face声明中font-weight值的重要性。为了将自定义字体应用于标题样式,即所有标题标签,重要的是字体的粗细要高于正常值。否则将应用默认字体。如果没有应用默认字体,它将回退到默认字体Serif > Times New Roman,字体粗细为bold。

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