如何为多个页面分离具有固定页眉和页脚的正文内容

13

我有三个不同的部分,分别是headerbodyfooter,用于创建PDF。

头部分将始终出现在每一页的顶部,并且它将保持固定。

 ______________________
|        header        |
|______________________|

问题出在正文内容,如果内容很长就会超过一页。

 ______________________
|                      |
|                      |
|        body          |
|                      |
|                      |
|______________________|

底部页脚会始终出现在每个页面的底部,并且它也会固定在那里。

 ______________________
|        footer        |
|______________________|

所以如果内容很多,创建了两个页面,那么我应该得到两个页面:

那么如果内容很多,创建了两个页面,我应该得到两个页面:

 ______________________
|        header        |
|______________________|
|                      |
|                      |
|        Body Part1    |
|                      |
|                      |
|______________________|
|        footer        |
|______________________|

而且

 ______________________
|        header        |
|______________________|
|                      |
|                      |
|        Body part2    |
|                      |
|                      |
|______________________|
|        footer        |
|______________________|

我尝试使用表格格式,它在标题和内容方面运作良好,但对于页脚则无法正常工作。页脚只会出现在第二页的底部而不是第一页。

我正在使用 laravel dompdf

希望能得到任何帮助。


生成PDF文件从HTML - Drone
你在用什么插件实现这个功能的? - Gaurav Aggarwal
我正在使用Laravel的dompdf,只是使用在线URL来检查并告诉我的问题。 - Drone
你试过使用page-break-before和page-break-after CSS规则吗?并像这里提到的那样添加一个固定的页眉和页脚:https://dev59.com/pnM_5IYBdhLWcg3wfTE0 - Kjell
你尝试过在这篇帖子中提到的解决方案吗?https://dev59.com/GGs05IYBdhLWcg3wDtpn#7489564 - d.coder
显示剩余4条评论
4个回答

11

HTML假定元素以不间断的序列呈现,而打印页面需要将内容分割成部分。在没有其他说明的情况下,解释器能够做的最好的工作就是将元素分隔到页面上,使大多数元素适合单个页面。

这篇详尽的SmashingMagazine文章会告诉你如何使用CSS设计用于打印的HTML。

对于你的问题来说,最重要的是,它将详细介绍@page区域,在整洁的纸张上。对你来说相关的可能是top-centerbottom-center区域(与文档所示看起来不同,这些区域很可能延伸到整个文档的宽度)。

使用这些区域,你可以通过CSS定义页眉和页脚,甚至根据折叠的一侧进行样式设计,如果你正在设计一本书的话。这些通过直接添加CSS内容来工作,因此不需要在你的HTML中添加任何标记就可以工作。

/* print a centered title on every page */
@top-center {
  content: "Title";
  color: #333;
  text-align: center;
}

/* print the title on the left side for left-hand pages, and vice versa */
@page:left {
  @top-left {
    content: "Title";
    color: #333;
  }
}
@page:right {
  @top-right {
    content: "Title";
    color: #333;
  }
}

虽然您正在使用Laravel,因此对您来说不是问题,但我所遇到的任何浏览器都不会打印这些区域,因此对于常规打印样式表来说并不实用。


虽然您可以使用CSS做很多事情,但您可能有太复杂的内容无法使用上述方式创建。在这种情况下,您可以使用一个带有position:fixed属性的元素,它将呈现在每个页面的顶部/底部,具体取决于您如何设置样式 - 例如像这样:

@media print {
  header {
    position: fixed;
    top: 0;
  }
  footer {
    position: fixed;
    bottom: 0;
  }
}

HTML:

<body>
  <header>
      above the content on screen, and on the top of every printed page
  </header>
  <main>
      content that is flowing and behaving as you would expect it
  </main>
  <footer>
      below the content on screen, and on the bottom of every printed page
  </footer>
</body>

我在编程中分别使用了以下两个代码:
  1. http://screencast.com/t/4MPlcOYy2J
  2. http://screencast.com/t/yjFkiNp3vNsA 从这两个代码中,我得到的输出结果是相同的:http://screencast.com/t/AkVbIEuRxUXO
- Drone
第一张截图中的代码应该按照您设置的方式工作。您确定您正在查看设置了“print”媒体类型的查看器吗?为了测试这一点,请删除@media print {和闭合}元素;或者您可以告诉浏览器渲染打印预览;在Firefox中,通过在开发人员控制台中输入media emulate print来实现。如果之后它仍然没有正确显示,那么您可能有其他冲突的CSS,或者dompdf正在干扰标记,破坏样式(不太可能)。 - TheThirdMan
我不知道我有多倒霉:现在我正在使用这个:http://screencast.com/t/EecyD023C9 并且得到这个作为输出的pdf:http://screencast.com/t/zCYJbCzzWOVT 看到红色的页眉和页脚,它忽略了第一页。 - Drone
老板:有了这段代码,我可以按照自己想要的方式制作 PDF:http://screencast.com/t/bFTGlTap2Je ,感谢您所有的支持。 - Drone
@Festo:很高兴能够提供帮助!请考虑点击勾选标记接受这个或其他已经帮助你解决问题的回答。这将向更广泛的社区表明你已经找到了解决方案,将其从未答复的队列中删除,并为回答者和你自己赢得一些声誉 - 当然,这不是必须要做的。 - TheThirdMan
显示剩余6条评论

4

请在完整视图中尝试以下代码。

header{
 height: 80px;
 border:1px solid red;
 position: fixed;
 width: 100%;
 top:0;
 background-color: red;
}
.content{
 border: 2px solid #000;
 margin-top: 80px;
 height: 100%;
 width: 100%;
}
footer{
 height: 80px;
 border:1px solid red;
 position: fixed;
 bottom: 0;
 width: 100%;
 background-color: red;
}
<body>

<header>
 <h1>Header</h1>
</header>

<div class="content">
 <h1>Content</h1>
 <p>one Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

 <p>2 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

 <p>3 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
 <p>4 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
 <p>5 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
 <p>6 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
 <p>7 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
 tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
 quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
 cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
 proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

<footer>
 <h1>Footer</h1>
</footer>


</body>


我按照你说的尝试了,但它忽略了第一页:http://content.screencast.com/users/Niklesh2/folders/Jing/media/7b046763-559a-4c58-a0ef-1717cff82ca3/2016-08-10_1219.png - Drone
@Festo,你能否请参考我的更新答案?希望它有效! - Vishal Panara
@Festo 好的,你能否请参考我上次更新的 CSS? - Vishal Panara
1
先生:通过这段代码,我能够按照自己的意愿生成PDF文件:http://screencast.com/t/bFTGlTap2Je,感谢您一直以来的支持。 - Drone
你可能需要添加一些页面边距(@page { margin: 120px 50px; }),然后使用负定位(header { top: -100px; ... };)将页眉/页脚放置在该空间中。如果不这样做,你可能会发现页眉/页脚与内容重叠。 - BrianS

3

我再次查看了这个有用的答案:https://dev59.com/ZnI-5IYBdhLWcg3wn5y5#1763683,并进行了一些更改和外部div标签,现在它对我有效。

我不知道laravel dompdf是如何将这个html转换为pdf的,但它对我有效。

以下是我的laravel代码:

Route::get('/', function () {
    $output = '<style>';
    $output .= '
        .divFooter {position: fixed;bottom: 20;text-align:center;}
                ';
    $output .= '</style>';
    $output .= '<div class="divFooter" style="color:red;"><h1>This is footer</h1></div>';
    $output .= '<table width="100%"><thead><tr><th><div style="color:red;"><h1>This is header</h1></div><th></tr></thead>';
    $output .= '<tbody><tr><td>';
    $output .= 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</td></tr>
      .........................
      .........................
      .........................
    ';
    $output .= '</tbody></table>';
    $pdf = App::make('dompdf.wrapper');
    $pdf->loadHTML($output);
    return $pdf->stream();
});

生成 PDF 类似于这样:http://content.screencast.com/users/Niklesh2/folders/Jing/media/13bb7a6f-f280-46db-94df-1af6270b4b02/2016-08-10_1713.png。很抱歉我无法告诉您它是如何工作的。但对于那些使用 Laravel dompdf 的人可能会有所帮助。祝愉快!

0

基本上,这种类型的应用程序被称为单页应用程序

> 在这种要求中,请利用AngularJs的力量,它具有路由的优势。

<html>

   <head>
      <title>Angular JS Views</title>
      <script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
      <script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script>
   </head>

   <body>
      <h2>AngularJS Sample Application</h2>
      <div ng-app = "mainApp">
         <p><a href = "#addStudent">Add Student</a></p>
         <p><a href = "#viewStudents">View Students</a></p>
         <div ng-view></div>

         <script type = "text/ng-template" id = "addStudent.htm">
            <h2> Add Student </h2>
            {{message}}
         </script>

         <script type = "text/ng-template" id = "viewStudents.htm">
            <h2> View Students </h2>
            {{message}}
         </script>
      </div>

      <script>
         var mainApp = angular.module("mainApp", ['ngRoute']);
         mainApp.config(['$routeProvider', function($routeProvider) {
            $routeProvider.

            when('/addStudent', {
               templateUrl: 'addStudent.htm',
               controller: 'AddStudentController'
            }).

            when('/viewStudents', {
               templateUrl: 'viewStudents.htm',
               controller: 'ViewStudentsController'
            }).

            otherwise({
               redirectTo: '/addStudent'
            });
         }]);

         mainApp.controller('AddStudentController', function($scope) {
            $scope.message = "This page will be used to display add student form";
         });

         mainApp.controller('ViewStudentsController', function($scope) {
            $scope.message = "This page will be used to display all the students";
         });

      </script>

   </body>
</html>

请您告诉我,是否正在寻找除此之外的其他替代方案。 - Biyu
我不明白,我该如何从你的代码中生成PDF文件,请详细解释一下。幸运的是,我正在使用Angular和Laravel,如果可以通过Angular实现这个功能就太好了。 - Drone

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