我正在尝试使用 wkhtmltopdf.exe 将 HTML 文档呈现为 PDF,我从 C# Web 应用程序调用它。
HTML 文档需要在每个页面上都出现页脚和页眉,这可以通过指定 --header-html <a path>
使用 wkhtmltopdf 实现。作为论据。
但是,页脚是从 Razor View 动态呈现的,我宁愿不必将它存储在磁盘上的临时文件中并使用该路径,但我想使用已经在内存中的呈现 HTML。这对于文档本身是可能的,通过写入 StandardInput
流,像这样:
var wkhtml = ConfigurationManager.AppSettings["WkHtmlToPdfPath"];
var p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = wkhtml;
p.StartInfo.Arguments = "-q -n --disable-smart-shrinking - -";
p.Start();
var stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(template);
stdin.Dispose();
是否可以对页眉和页脚 HTML 做同样的事情,即以内联方式传递它而不必求助于临时文件?
我试过:
stdin.Write(string.Format("--footer-html {0} ", footer));
当然,它只是将其视为文档的一部分,而不是页脚。
我想动态渲染页脚和页眉的主要原因(主要)是由另一个问题引起的。虽然有一个动态的页眉和页脚会很好,但它主要是为了解决我必须链接到具有绝对路径的图像的问题(即:C:\templates\images\logo.png),因为相对路径(即: images/logo.png)在你使用 stdin 时不起作用,只是传入一个 HTML 字符串 blob,所以我需要在运行时通过 Razor 插入绝对路径。
对于这个问题,我试过设置进程的工作目录来匹配相对路径,但是没有用:
p.StartInfo.WorkingDirectory = @"C:\templates";
如果我能解决那个问题,那也就解决了 90% 的问题。
最佳答案
请注意,如果你解决了这个 JulianR,我也会假设你在 MVC(?) 如果没有,您可以忽略下面的一些初始代码,但我有类似的情况,由于网站的安全和登录部分,我需要将输出直接流式传输到 wkhtmltopdf。
首先,在 Controller 中,您可以使用任何适用的母版页(本身可能使用页眉和页脚)拉入显示所需的 View :
var view = ViewEngines.Engines.FindView(ControllerContext, myViewName, myMasterPageLayout);
然后,您可以使用任何必要的 ViewData、Tempdata 等获取此 View 的当前信息,并将其存储在一个字符串中(内容如下):
string content;
ViewData.Model = model;
using (var writer = new System.IO.StringWriter())
{
var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
view.View.Render(context, writer);
writer.Flush();
content = writer.ToString();
writer.Close();
}
在此阶段,如果需要,您实际上可以修改字符串中的输出 html - 例如将任何本地路径更改为完整路径
输出 HTML 后,您只需将其传递给 wkhtmltopdf:
var p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
//Other parameters as required
byte[] file;
try
{
p.Start();
byte[] buffer = new byte[32768];
using (System.IO.StreamWriter stdin = p.StandardInput)
{
stdin.AutoFlush = true;
stdin.Write(content);
}
using (MemoryStream ms = new MemoryStream())
{
ms.Position = 0;
p.StandardOutput.BaseStream.CopyTo(ms);
file = ms.ToArray();
}
p.StandardOutput.Close();
// wait or exit
p.WaitForExit(60000);
// read the exit code, close process
int returnCode = p.ExitCode;
}
然后您将获得一个字节数组,其中包含整个页面的 PDF 内容。
关于c# - WkHtmlToPDF - 使用标准输入和页眉/页脚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13079774/