【问题标题】:Adding Headers, Footers, and Page Numbers to HTML Page Converted to PDF iText 7将页眉、页脚和页码添加到转换为 PDF iText 7 的 HTML 页面
【发布时间】:2018-06-20 17:00:35
【问题描述】:

大家好,提前感谢您的帮助。我正在学习 iText 7,并正在创建一个从 URL 中提取网页并将其转换为 PDF 的应用程序。我已经完成了非常基本的工作,即抓取页面,将其转换为 PDF,然后将其写入磁盘。我接下来要完成的是添加页眉和页脚以及y的第x页。我试过了:

        @media print {
        @page {
            size: 8.5in 5.5in portrait;
            margin-left: 0.5cm;
            margin-right: 0.5cm;
            margin-bottom: .5cm;
            padding-bottom: 3.5cm;
            background: #FFF;
        }

        thead { display: table-header-group; }
        tfoot { display: table-footer-group; }
    }

这似乎将页眉和页脚放在每一页上,尽管文档的最后一页将页脚放在最后一个元素出现的位置之后(不理想)。由于我正在抓取页面,因此我不确定如何添加页码和计数。所以我的问题是如何解决这个问题,即我应该坚持使用媒体查询,还是应该生成 PDF,通过使用某种类型的处理程序插入页眉和页脚的循环(或者我应该在创建初始文件)。我现在有一些关于分页的教程,但没有与转换网页相结合,所以我对如何继续感到困惑(也许是不必要的)。任何帮助将不胜感激。

我试过了:

        @media print {
        @page {
            size: 8.5in 5.5in portrait;
            margin-left: 0.5cm;
            margin-right: 0.5cm;
            margin-bottom: .5cm;
            padding-bottom: 3.5cm;
            background: #FFF;

        @bottom-right {
        content: "Page " counter(page) " of " counter(pages);
        }   
        }

        thead { display: table-header-group; }
        tfoot { display: table-footer-group; }
    }

但在 HTML 或转换后的 PDF 中不显示页码。我需要使用:thead { display: table-header-group; } tfoot { display: table-footer-group; } to force the header and footer to display on each page. Obviously I'm not handling this correctly, but don't know what to try next.

`

在此处输入代码

【问题讨论】:

  • 我已经更新了我的答案。 我强烈建议您阅读本教程。 如果您定义了 new MediaDeviceDescription(MediaType.PRINT),则 iText 只会查看 CSS 的 @page 部分!你这样做了吗?
  • @BrunoLowagie 为了使页面工作,我们是否应该在将 HTML 转换为 PDF 后定义这个新的 MediaDeviceDescription(MediaType.PRINT)?
  • @BrunoLowagie 我正在使用这个 css ol.anchorLink a::after { content: leader('.') target-counter(attr(href), page); } 在目录中的链接之后显示页码我们有什么要在 mediaDeviceDescription 中配置的吗?

标签: itext7


【解决方案1】:

您需要页眉和页脚,但查看您的 CSS,我看不到您在任何地方定义页眉或页脚(<thead><tfoot> 用于表格,而不是用于页面)。您想为每个页面添加“第 X 页,共 Y”,但我没有看到您在任何地方定义该内容。

请阅读Chapter 2 的将 HTML 转换为 PDF 的教程。在其中一个示例中,您将看到:

@page {
    @bottom-right {
        content: "Page " counter(page) " of " counter(pages);
    }
}

这在每个页面的右下角定义了一个页脚,内容为“页面X of Y”,其中X 将是当前页面,Y 是总页面数。

阅读有关@page rule 的更多信息,您会发现您还可以定义@bottom-left@bottom-center@top-left 等等。

还要注意您使用@media print 的事实,这意味着如果您定义了正确的媒体查询,iText 只会查看这些括号之间的任何内容。请参阅教程的Chapter 3

最终更新:

我从tutorial中提取了以下示例:C03E02_Print

public static void main(String[] args) throws IOException {
    File file = new File(TARGET);
    file.mkdirs();
    new Kmcnet().createPdf(BASEURI, SRC, DEST);
}

public void createPdf(String baseUri, String src, String dest) throws IOException { 
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.PRINT);
    properties.setMediaDeviceDescription(mediaDeviceDescription);
    HtmlConverter.convertToPdf(new FileInputStream(src), new FileOutputStream(dest), properties);
}

我拿了sxsw.html 页面,然后像这样更改了sxsw_print.css

@page {
    @top-left {
        content: "HEADER";
    }
    @top-center {
        content: "READ THE TUTORIAL";
    }
    @top-right {
        content: "kmcnet";
    }
    @bottom-left {
        content: "FOOTER";
    }
    @bottom-center {
        content: "Page " counter(page) " of " counter(pages);
    }
    @bottom-right {
        content: "The end";
    }
}

我运行了代码,结果如下:

OP,kmcnet,声称页面上没有“Page X of Y”,但如果仔细观察,您可以在中间看到“Page 1 of 2”和“Page 2 of 2”屏幕截图上的页面底部。此外,kmcnet 声称无法在页眉或页脚中添加客户名称,但如果您查看屏幕截图,您可以清楚地看到页面右上角的“kmcnet”。

然后我拿了movies2.html 文件,并像这样更改了内联CSS:

<style>
@media print {
    @page {
        @top-left {
            content: "HEADER";
        }
        @top-center {
            content: "READ THE TUTORIAL";
        }
        @top-right {
            content: "kmcnet";
        }
        @bottom-left {
            content: "FOOTER";
        }
        @bottom-center {
            content: "Page " counter(page) " of " counter(pages);
        }
        @bottom-right {
            content: "The end";
        }
    }
}
</style>

我在该 HTML 上运行了 C03E02_Print 示例,结果显示了类似的页眉和页脚:

原来的问题是:

接下来我要完成的是添加页眉和页脚以及y的第x页。

我认为我的回答和教程充分解释了如何做到这一点。不幸的是,OP坚持说我的答案不起作用,也不是教程中写的内容。

我会把这个问题作为题外话,更具体地说,作为一个无法重现的问题:

【讨论】:

  • 和 用于强制在每个页面上显示页眉和页脚。我嵌套了
  • 呃...好吧,但是&lt;thead&gt;&lt;tfoot&gt; 中的t 指的是&lt;table&gt;,不是吗?请参阅w3schools.com/tags/tag_thead.asp 为什么要使用与 table 相关的标签来为 page 添加页眉和页脚?
  • @kmcnet 我的印象是您认为阅读本教程是在浪费时间。因此,您浪费了您的时间和我的时间。请阅读教程。你会节省时间!
  • 很抱歉你有这种感觉。我确实阅读了教程。但是,我也在尝试向每一页添加页眉和页脚文本。我之前做过研究:forums.asp.net/t/2139996.aspx?Printable+Page,这个“修复”在很多文章中都可以找到。所以你假设我没有阅读教程也浪费了我们的时间。我显然不明白如何让这个工作。
  • 您所指的页面有@bottom-left@bottom-center@top-left、...我解释过的东西。但是,您忽略了 @media screen@media print 之间的区别。请不要使用您不理解的“修复”。如果您找到“修复”,请检查它并了解后果和影响。现在您知道了,应该很容易解决您的问题。
【解决方案2】:

我能够通过修改 html 页眉中的 css 样式来创建自定义页脚。此示例使用 ASP.NET MVC。样式在视图中动态填充。如果每个客户的页脚不同,最好为每个客户生成一个 pdf,然后将它们合并。

剃刀视图

@model YourNamespace.ViewModels.XYZViewModel
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <style type="text/css">
        @@page {
            @@bottom-left {
                content: "@Model.FullName";
            }

            @@bottom-center {
                content: "@DateTime.Now.ToShortDateString()";
            }

            @@bottom-right {
                content: "Page " counter(page);
            }
        }
    </style>
</head>
...............

然后可以将视图生成为 HTML

public static string RenderView<TModel>(this Controller controller, string viewName, TModel model)
        {
            using (var sw = new StringWriter())
            {
                controller.ViewData.Model = model;
                var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, "");
                var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
                viewResult.View.Render(viewContext, sw);
                viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);
                return sw.GetStringBuilder().ToString();
            }
        }

在控制器中将视图呈现为 HTML 的调用

string html = this.RenderView(@"~\Views\Folder\ViewName.cshtml", viewModel);

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签