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

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

问题描述

我使用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

我真的需要一些投入在这个阶段。因此,任何帮助是非常AP preciated!

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

仅供参考写文件和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);
    }
}

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

我不能得到这个相对路径工作。因此,我所做反而是prepends有根路径的所有路径的方法。它解决了我的问题,所以也许它会解决你的:

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去了解它。由于缺乏时间不够我只是做了快速和肮脏的UrlEn code以上。

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 图像引用为 SRC =mlp.png C:\ Program Files文件\ wkhtmltopdf \ BIN \ mlp.png ,对不对?我认为,它的作品,因为你的图像文件在同一文件夹中wkhtmltopdf ...所以尝试 WorkingDirectory 设置到该目录,看看会发生什么。

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在HMTL相对路径与重定向输入/输出流将无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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