wkhtmltopdf在HTML相对路径与重定向输入/输出流将无法正常工作 [英] wkhtmltopdf relative paths in HTML with redirected in/out streams won't work

查看:1461
本文介绍了wkhtmltopdf在HTML相对路径与重定向输入/输出流将无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用wkhtmltopdf.exe(0.12.0最终版本),以从HTML文件生成PDF文件,我这样做是使用.NET C#

I am using wkhtmltopdf.exe (version 0.12.0 final) to generate pdf files from html files, I do this with .NET C#

我的问题是越来越JavaScript中,样式表和图像只由在html指定相对路径工作。现在我有工作,如果我使用绝对路径。但它不与相对路径,这使得整个HTML生成一个位复杂工作。我已经煮我做什么倒在下面的例子:

My problem is getting javascript, stylesheets and images to work by only specifying relative paths in the html. Right now I have it working if I use absolute paths. But it doesn't work with relative paths, which makes the whole html generation a bit to complicated. I have boiled what I do down to the following example:

string CMDPATH = @"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe";
string HTML = string.Format(
    "<div><img src=\"{0}\" /></div><div><img src=\"{1}\" /></div><div>{2}</div>",
    "./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文件中工作。有是错误流中没有数据。

I have tried relative paths like: "./sohlogo.png" and simply "sohlogo.png" both displays correctly in the browser via the html file. But none of them work in the pdf file. There is no data in the error stream.

下面的命令行工作方式和相对路径的魅力:

The following commandline works like a charm with the relative paths:

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

我真的需要在此阶段一些投入。 !因此,任何的帮助深表感谢。

I could really need some input at this stage. So any help is much appreciated!

仅供参考,WriteFile的和CopyStream方法是这样的:

Just for reference the WriteFile and CopyStream methods looks like this:

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);
    }
}



编辑:我的解决方法为新阮。

我不能得到这个相对路径工作。所以我做了什么,而不是是预先考虑了根路径的所有路径的方法。它解决了我的问题,所以也许它会解决你的:

I could not get this to work with relative paths. So what I did instead was a method that prepends all paths with a root path. It solves my problem so maybe it will solve yours:

/// <summary>
/// Prepends the basedir x in src="x" or href="x" to the input html text
/// </summary>
/// <param name="html">the initial html</param>
/// <param name="basedir">the basedir to prepend</param>
/// <returns>the new html</returns>
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 ***喜欢的System.Uri方法.EscapeDataString()。但是,他们最终做剧烈的URL编码wkhtmltopdf去了解它。由于缺乏时间不够我只是做了上面的快速和肮脏以UrlEncode。

I tried different System.Uri.Escape*** methods like System.Uri.EscapeDataString(). But they ended up doing to severe url encoding for wkhtmltopdf to understand it. Because of lack of lack of time I just did the quick and dirty UrlEncode above.

推荐答案

展望快,我觉得麻烦可能与

Looking quickly, I think the trouble might be with

psi.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;



我认为如果路径是指着。我假设

I think that is where the paths are pointing at. I'm assuming that

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

工作意味着你的形象在的test.html <引用/ code>为 SRC =mlp.png C:\Program Files\wkhtmltopdf\bin\mlp巴纽,对不对?我认为,它的工作原理,因为你的图像文件在同一文件夹中wkhtmltopdf ...所以尝试设置工作目录到该目录,看看会发生什么。

working means that your image referenced inside test.html as src="mlp.png" is at c:\Program Files\wkhtmltopdf\bin\mlp.png, right? I think that it works because your image file is in the same folder as wkhtmltopdf... so try setting the WorkingDirectory to that directory and see what happens.

这篇关于wkhtmltopdf在HTML相对路径与重定向输入/输出流将无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆