Мой взгляд на вещи с 2018 года.
Я использую асинхронный. Я транслирую в и из wkhtmltopdf. Я создал новый StreamWriter, потому что wkhtmltopdf ожидает utf-8 по умолчанию, но при запуске процесса ему присваивается другое значение.
Я не включил много аргументов, поскольку они варьируются от пользователя к пользователю. Вы можете добавить то, что вам нужно, используя дополнительные Args.
Я удалил p.WaitForExit (...), так как не обрабатывал, если он не работает, и он все равно зависнет на await tStandardOutput
. Если требуется тайм-аут, вам придется вызывать Wait(...)
для различных задач с помощью символа отмены или тайм-аута и обрабатывать соответственно.
public async Task<byte[]> GeneratePdf(string html, string additionalArgs)
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = @"C:\Program Files\wkhtmltopdf\wkhtmltopdf.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
Arguments = "-q -n " + additionalArgs + " - -";
};
using (var p = Process.Start(psi))
using (var pdfSream = new MemoryStream())
using (var utf8Writer = new StreamWriter(p.StandardInput.BaseStream,
Encoding.UTF8))
{
await utf8Writer.WriteAsync(html);
utf8Writer.Close();
var tStdOut = p.StandardOutput.BaseStream.CopyToAsync(pdfSream);
var tStdError = p.StandardError.ReadToEndAsync();
await tStandardOutput;
string errors = await tStandardError;
if (!string.IsNullOrEmpty(errors)) { /* deal/log with errors */ }
return pdfSream.ToArray();
}
}
Вещи, которые я там не включил, но может быть полезен, если у вас есть изображения, CSS или другие вещи, которые wkhtmltopdf должен будет загрузить при рендеринге html-страницы:
- вы можете передать куки аутентификации используя --cookie
- в заголовке html-страницы вы можете установить базовый тег с помощью href, указывающего на сервер, и wkhtmltopdf будет использовать его, если необходимо,