cómo pasar html como una cadena en lugar de url en wkhtmltopdf usando asp.net, C#?cómo pasar html como una cadena usando wkhtmltopdf?
Respuesta
Redirigir STDIN es probablemente la forma más fácil de lograr lo que estás tratando de hacer.
Un método para redirigir STDIN con wkhtmltopdf (en ASP.Net) es el siguiente:
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);
}
Tenga en cuenta que el código anterior se supone que hay un directorio temporal disponible en el directorio de la aplicación. Además, debe habilitar explícitamente el acceso de escritura a ese directorio para la cuenta de usuario utilizada al ejecutar el proceso IIS.
No consigo que esto funcione con imágenes y hojas de estilo referenciadas. Es eso posible? Cuando ejecuto la línea de comandos con archivos en el disco, funciona. – smerlung
@smerlung Asegúrese de que la aplicación web tenga acceso a los archivos a los que hace referencia. Cuando se ejecuta desde la línea de comando, se está ejecutando como su inicio de sesión; cuando se ejecuta desde el servidor web, se está ejecutando como el inicio de sesión del servidor web, que puede no tener acceso a los archivos que está utilizando. Además, asegúrese de que la ruta a los archivos también tenga sentido desde esa ubicación. Por ejemplo, si hace referencia a '.. \ styles \ style.css', entonces debe haber un directorio' styles', 'arriba' donde está ejecutando el programa, que contiene el archivo 'style.css'. –
Lo tengo trabajando usando rutas absolutas. Pero eso no es muy bueno. Entiendo lo que dices, pero mi problema es que no entiendo dónde está "funcionando" el proceso. He intentado diferentes opciones para WorkingDirectory pero no pude resolverlo? – smerlung
STDIn y STDOut se han redirigido en este ejemplo, por lo que no debería necesitar archivos en absoluto.
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);
}
}
}
no es necesario ** Cerrar ** y ** Eliminar ** el Proceso, hace lo mismo. Solo deséchelo o póngalo en una construcción en uso. Lo mismo aplica para las transmisiones ... –
Ahora solo deseche se llama –
sí, esto es mejor :) –
Sé que esta es una publicación anterior, pero quiero que los futuros desarrolladores tengan esta opción. Tenía la misma necesidad, y la idea de tener que iniciar un proceso en segundo plano solo para obtener un PDF dentro de una aplicación web es terrible.
Aquí hay otra opción: https://github.com/TimothyKhouri/WkHtmlToXDotNet
Es una envoltura alrededor nativa .NET wkhtmltopdf.
Código de ejemplo aquí:
var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");
Nota, no es seguro para subprocesos a partir de ahora - Estoy trabajando en eso. Entonces use un monitor o algo así o un candado.
- 1. html a pdf con wkhtmltopdf
- 2. Cómo pasar una cadena como una etiqueta de UIButton
- 3. Obtener código fuente HTML como una cadena
- 4. ¿Cómo puedo pegar HTML en una cadena usando Perl?
- 5. Cómo recuperar contenido HTML de WebView (como una cadena)
- 6. ¿Cómo obtener todo el documento HTML como una cadena?
- 7. jQuery AJAX: ¿Cómo pasar etiquetas HTML grandes como parámetros?
- 8. Cómo guardar una cadena base64 como una imagen usando ruby
- 9. wkhtmltopdf - número de codificación
- 10. wkhtmltopdf RuntimeError (Ubicación desconocida de wkhtmltopdf)
- 11. Cómo pasar cadena html a webview en android
- 12. Asir las entradas ocultas como una cadena (usando PHP Simple HTML DOM Parser)
- 13. Usando archivos .html como JSPs
- 14. wkhtmltopdf saltos de página automáticos
- 15. Cómo validar una cadena como DateTime usando FluentValidation
- 16. Rendimiento de wkhtmltopdf
- 17. Pasar varios objetos JSON como datos usando jQuery $ .ajax()
- 18. obtener toda HTML como una cadena de HTMLDocument
- 19. Cómo pasar una clase parametrizada como argumento
- 20. ¿Cómo puedo pasar una propiedad como delegado?
- 21. hash una cadena de contraseña usando SHA512 como C#
- 22. wkhtmltopdf stylesheets
- 23. Cómo pasar GridView como ConverterParameter
- 24. usando pitón, eliminar las etiquetas HTML/formato de una cadena
- 25. cómo pasar xml como parámetro usando el método POST y usando jquery ajax
- 26. encabezado wkhtmltopdf en cada página
- 27. El comando wkhtmltopdf falla
- 28. ¿Cómo puedo pasar tipos complejos como objetos usando servicios web?
- 29. Cómo exportar PDF a OutputStream con wkhtmltopdf en Java
- 30. wkhtmltopdf segfaults
Probablemente sería más fácil redirigir stdin y pasar la cadena de esa manera. También podría escribir el texto en un archivo (aunque eso no va a escalar muy bien, por supuesto). –
¿Podría mostrar un ejemplo? – Eugene