C# 如何使用wkhtmltopdf将html作为字符串传递?
如何使用asp.net、c#?将html作为字符串而不是url在wkhtmltopdf中传递,重定向STDIN可能是完成您尝试的操作的最简单方法 使用wkhtmltopdf(在ASP.Net中)重定向STDIN的一种方法如下:C# 如何使用wkhtmltopdf将html作为字符串传递?,c#,asp.net,wkhtmltopdf,C#,Asp.net,Wkhtmltopdf,如何使用asp.net、c#?将html作为字符串而不是url在wkhtmltopdf中传递,重定向STDIN可能是完成您尝试的操作的最简单方法 使用wkhtmltopdf(在ASP.Net中)重定向STDIN的一种方法如下: private void WritePDF(string HTML) { string inFileName, outFileName, tempPath; P
private void WritePDF(string HTML)
{
string inFileName,
outFileName,
tempPath;
Process p;
System.IO.StreamWriter stdin;
ProcessStartInfo psi = new ProcessStartInfo();
tempPath = Request.PhysicalApplicationPath + "temp\\";
inFileName = Session.SessionID + ".htm";
outFileName = Session.SessionID + ".pdf";
// run the conversion utility
psi.UseShellExecute = false;
psi.FileName = "c:\\Program Files (x86)\\wkhtmltopdf\\wkhtmltopdf.exe";
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
// note that we tell wkhtmltopdf to be quiet and not run scripts
// NOTE: I couldn't figure out a way to get both stdin and stdout redirected so we have to write to a file and then clean up afterwards
psi.Arguments = "-q -n - " + tempPath + outFileName;
p = Process.Start(psi);
try
{
stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(HTML);
stdin.Close();
if (p.WaitForExit(15000))
{
// NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
//Response.WriteFile(tempPath + outFileName);
}
}
finally
{
p.Close();
p.Dispose();
}
// delete the pdf
System.IO.File.Delete(tempPath + outFileName);
}
请注意,上面的代码假设应用程序目录中有一个可用的临时目录。此外,对于运行IIS进程时使用的用户帐户,必须显式启用对该目录的写访问。在本例中,STDIn和STDOut已被重定向,因此您根本不需要文件
public static class Printer
{
public const string HtmlToPdfExePath = "wkhtmltopdf.exe";
public static bool GeneratePdf(string commandLocation, StreamReader html, Stream pdf, Size pageSize)
{
Process p;
StreamWriter stdin;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Path.Combine(commandLocation, HtmlToPdfExePath);
psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);
// run the conversion utility
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
// note: that we tell wkhtmltopdf to be quiet and not run scripts
psi.Arguments = "-q -n --disable-smart-shrinking " + (pageSize.IsEmpty? "" : "--page-width " + pageSize.Width + "mm --page-height " + pageSize.Height + "mm") + " - -";
p = Process.Start(psi);
try {
stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(html.ReadToEnd());
stdin.Dispose();
CopyStream(p.StandardOutput.BaseStream, pdf);
p.StandardOutput.Close();
pdf.Position = 0;
p.WaitForExit(10000);
return true;
} catch {
return false;
} finally {
p.Dispose();
}
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
output.Write(buffer, 0, read);
}
}
}
我知道这是一篇比较老的帖子,但我希望未来的开发者能有这个选择。我也有同样的需求,而仅仅为了在web应用程序中获取PDF而不得不启动后台进程的想法非常糟糕 还有一个选择: 它是围绕wkhtmltopdf的.NET本机包装 此处的示例代码:
var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");
var pdfData=HtmlToXConverter.ConvertToPdf(“COOOL!”);
注意,目前它还不是线程安全的-我正在研究这个问题。因此,只需使用监视器或其他东西或锁。重定向stdin并以这种方式传递字符串可能是最容易的。您也可以将文本写入文件(当然,这不会很好地扩展)。您可以演示一个示例吗?无需关闭和处理流程,它也会执行相同的操作。只需处置它,或将其放入使用构造中。流也是一样。+1很棒的帖子,我最近用类似的代码写了这篇文章:很棒的帖子它帮助了很多人。在争论的结尾,`-`的目的是什么?我知道它与输出到STDOUT有关,但这是一个wkhtmltopdf构造,还是对任何命令行都有效?@Walter Stabosz,请看这里。使用-告诉wkhtmltopdf使用标准流。我无法将其用于引用的图像和样式表。有可能吗?当我使用磁盘上的文件运行命令行时,命令行可以工作。@smerlung请确保web应用程序可以访问您正在引用的文件。从命令行运行时,您作为登录名运行;从web服务器运行时,您以web服务器登录名运行,该登录名可能无法访问您正在使用的文件。此外,还要确保文件的路径在该位置也是合理的。例如,如果您正在引用
。\styles\style.css
,则需要在运行程序的“上方”有一个styles
目录,其中包含style.css
文件。但这不是很好。我明白你的意思,但我的问题是我不明白流程“运行”在哪里。我尝试了不同的工作目录选项,但没能找到它?