Как передать html в виде строки с помощью wkhtmltopdf?
как передать html как строку вместо url в wkhtmltopdf, используя asp.net, С#?
Ответы
Ответ 1
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);
}
}
}
Ответ 2
Перенаправление STDIN, вероятно, самый простой способ выполнить то, что вы пытаетесь сделать.
Один из способов перенаправления STDIN с помощью wkhtmltopdf (в ASP.Net) выглядит следующим образом:
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);
}
Обратите внимание, что в приведенном выше коде предполагается, что в каталоге приложения есть каталог temp. Кроме того, вы должны явно разрешить доступ на запись к этому каталогу для учетной записи пользователя, используемой при запуске процесса IIS.
Ответ 3
Я знаю, что это более старая должность, но я хочу, чтобы будущие разработчики имели этот вариант. У меня была такая же потребность, и идея начать фоновый процесс просто для того, чтобы получить PDF внутри веб-приложения, ужасна.
Вот еще один вариант: https://github.com/TimothyKhouri/WkHtmlToXDotNet
Это родная оболочка .NET вокруг wkhtmltopdf.
Пример кода здесь:
var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");
Обратите внимание, что это не потокобезопасно, как сейчас. Я работаю над этим. Так что просто используйте монитор или что-то или замок.