是否可以通过在C#MVC中打开浏览器传递url来创建PDF

时间:2017-08-14 06:41:54

标签: asp.net asp.net-mvc-4 c#-4.0 itext

我想通过在开放浏览器中传递网址来创建pdf。可能吗?任何一个例子。

1 个答案:

答案 0 :(得分:2)

让我们以此页面为例,让我们编写一个名为createPdf()的方法,该方法将URL指向网址,并使用String表示生成的PDF的路径。可以这样调用该方法:

app.createPdf(
    new URL("https://stackoverflow.com/questions/45668769"),
    "stackoverflow_question45668769.pdf");

实现此方法的最简单方法如下:

public void createPdf(URL url, String dest) throws IOException {
    HtmlConverter.convertToPdf(url.openStream(), new FileOutputStream(dest));
}

我们不需要浏览器,URL对象打开InputStream,直接从Web服务器读取字节。这些字节由pdfHTML附加组件解析。不需要浏览器或类似WebKit的软件。

结果如下:

enter image description here

这很好,但是有一个小问题:iText 7使用的默认页面大小是A4,并且没有足够的空间容纳所有内容。

让我们旋转页面,让我们定义一个媒体查询,告诉iText更多关于“屏幕大小”(在我们的例子中,实际上是页面大小):

public void createPdf(URL url, String dest) throws IOException {
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    PageSize pageSize = PageSize.A4.rotate();
    pdf.setDefaultPageSize(pageSize);
    ConverterProperties properties = new ConverterProperties();
    MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
    mediaDeviceDescription.setWidth(CssUtils.parseAbsoluteLength(String.valueOf(pageSize.getWidth())));
    properties.setMediaDeviceDescription(mediaDeviceDescription);
    HtmlConverter.convertToPdf(url.openStream(), pdf, properties);
}

现在结果如下:

enter image description here

非常整洁,不是吗?

Stack Overflow还有一个打印页面时使用的CSS。因此,让我们再创建一个createPdf()方法的变体:

public void createPdf(URL url, String dest) throws IOException {
    ConverterProperties properties = new ConverterProperties();
    MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.PRINT);
    properties.setMediaDeviceDescription(mediaDeviceDescription);
    HtmlConverter.convertToPdf(url.openStream(), new FileOutputStream(dest), properties);
}

现在我们告诉iText我们正在创建用于打印而不是用于屏幕的PDF。结果如下:

enter image description here

你看到了区别吗?以前的PDF文件都包含几页。此PDF只有一页长,因为Stack Overflow使用的print.css的定义方式是删除问题打印版本的所有不必要信息。

注意:

我使用Java代码是因为我是Java开发人员,而不是C#开发人员。但是:iText 7和pdfHTML for Java(几乎)与iText 7和pdf的pdfHTML相同。所有iText开发最初都是用Java完成的,然后自动转发到C#。除了为方法名称的第一个字符更改为大写的小写外,您需要的方法名称是相同的。您还必须调整Stream个对象。对于C#开发人员来说,这应该不是问题。

重要:

如果您使用HTMLWorker将HTML转换为PDF,请放弃所有希望。编写HTMLWorker是为了将HTML代码的小片段转换为PDF。 HTMLWorker的代码是以快速而肮脏的方式编写的,并且在不丢弃大部分代码的情况下无法扩展。这就是HTMLWorker被放弃的原因。它不再受支持,不应再使用它。

您正在使用XML Worker,请理解XML Worker基于iText 5. iText 5的设计早于构建HTML到PDF转换器的想法。 iText 5的架构不适合将网页转换为PDF。请不要期望与iText 5和XML Worker在此答案中添加的屏幕截图中显示的结果类似。

我们从头开始将iText重写为HTML转换为PDF转换。结果是iText 7.如果你想执行这个答案中显示的代码,你还需要一个到iText 7的pdfHTML插件。你需要一个(试用版)许可证密钥来编写这段代码。

许可证可以像这样加载:

LicenseKey.loadLicenseFile(pathToLicenseKey);

其中pathToLicenseKey是您在注册试用许可证或购买商业许可证以获取iText时获得的XML文件的路径。