带有重定向输入/输出流的HTML中的wkhtmltopdf相对路径将不起作用

我正在使用wkhtmltopdf.exe(版本0.12.0 final)从html文件生成pdf文件,我使用.NET C#

我的问题是只通过在html中指定相对路径来使javascript,样式表和图像工作。 现在,如果我使用绝对路径,我可以使用它。 但它不适用于相对路径,这使得整个html生成有点复杂。 我把我做的事情煮成了下面的例子:

string CMDPATH = @"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"; string HTML = string.Format( "
{2}
", "./sohlogo.png", "./ACLASS.jpg", DateTime.Now.ToString()); WriteFile(HTML, "test.html"); Process p; ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = CMDPATH; psi.UseShellExecute = false; psi.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; psi.CreateNoWindow = true; psi.RedirectStandardInput = true; psi.RedirectStandardOutput = true; psi.RedirectStandardError = true; psi.Arguments = "-q - -"; p = Process.Start(psi); StreamWriter stdin = p.StandardInput; stdin.AutoFlush = true; stdin.Write(HTML); stdin.Dispose(); MemoryStream pdfstream = new MemoryStream(); CopyStream(p.StandardOutput.BaseStream, pdfstream); p.StandardOutput.Close(); pdfstream.Position = 0; WriteFile(pdfstream, "test.pdf"); p.WaitForExit(10000); int test = p.ExitCode; p.Dispose();

我尝试过相对路径,例如:“。/ sohlogo.png”,只需“sohlogo.png”,它们都可以通过html文件在浏览器中正确显示。 但它们都不适用于pdf文件。 错误流中没有数据。

以下命令行的工作方式类似于具有相对路径的魅力:

 "c:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" test.html test.pdf 

在这个阶段我真的需要一些输入。 所以任何帮助都非常感谢!

仅供参考,WriteFile和CopyStream方法如下所示:

 public static void WriteFile(MemoryStream stream, string path) { using (FileStream writer = new FileStream(path, FileMode.Create)) { byte[] bytes = stream.ToArray(); writer.Write(bytes, 0, bytes.Length); writer.Flush(); } } public static void WriteFile(string text, string path) { using (StreamWriter writer = new StreamWriter(path)) { writer.WriteLine(text); writer.Flush(); } } 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); } } 

编辑:我对Neo Nguyen的解决方法。

我无法通过相对路径来实现这一点。 所以我所做的是一种方法,它使用根路径预先建立所有路径。 它解决了我的问题所以也许它会解决你的问题:

 ///  /// Prepends the basedir x in src="x" or href="x" to the input html text ///  /// the initial html /// the basedir to prepend /// the new html public static string MakeRelativePathsAbsolute(string html, string basedir) { string pathpattern = "(?:href=[\"']|src=[\"'])(.*?)[\"']"; // SM20140214: tested that both chrome and wkhtmltopdf.exe understands "C:\Dir\..\image.png" and "C:\Dir\.\image.png" // Path.Combine("C:/ html = Regex.Replace(html, pathpattern, new MatchEvaluator((match) => { string newpath = UrlEncode(Path.Combine(basedir, match.Groups[1].Value)); if (!string.IsNullOrEmpty(match.Groups[1].Value)) { string result = match.Groups[0].Value.Replace(match.Groups[1].Value, newpath); return result; } else { return UrlEncode(match.Groups[0].Value); } })); return html; } private static string UrlEncode(string url) { url = url.Replace(" ", "%20").Replace("#", "%23"); return url; } 

我尝试了不同的System.Uri.Escape.Sscape ***方法,如System.Uri.EscapeDataString()。 但他们最终对wkhtmltopdf进行了严格的url编码以理解它。 由于时间不够,我只是做了上面快速而脏的UrlEncode。

看起来很快,我认为可能会遇到麻烦

 psi.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; 

我认为这是路径指向的地方。 我在假设

 "c:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" test.html test.pdf 

工作意味着您在test.html引用的图像为src="mlp.png"位于c:\Program Files\wkhtmltopdf\bin\mlp.png ,对吗? 我认为它的工作原理是因为您的图像文件与wkhtmltopdf在同一个文件夹中…所以尝试将WorkingDirectory设置为该目录并查看会发生什么。