Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WkHtmlToPDF-使用标准文本和页眉/页脚_C#_Razor_Stdin_Wkhtmltopdf - Fatal编程技术网

C# WkHtmlToPDF-使用标准文本和页眉/页脚

C# WkHtmlToPDF-使用标准文本和页眉/页脚,c#,razor,stdin,wkhtmltopdf,C#,Razor,Stdin,Wkhtmltopdf,我正在尝试使用wkhtmltopdf.exe将HTML文档呈现为PDF格式,我从一个C#web应用程序调用它 HTML文档需要有页脚和页眉,页脚和页眉在每个页面上重复出现,这可以通过将--header HTML指定为参数使用wkhtmltopdf实现 但是,页脚是从Razor视图动态呈现的,我不希望将其存储在磁盘上的临时文件中并使用该路径,但我希望使用已在内存中呈现的HTML。通过写入StandardInput流,文档本身也可以这样做,如下所示: var wkhtml = Configurati

我正在尝试使用wkhtmltopdf.exe将HTML文档呈现为PDF格式,我从一个C#web应用程序调用它

HTML文档需要有页脚和页眉,页脚和页眉在每个页面上重复出现,这可以通过将
--header HTML
指定为参数使用wkhtmltopdf实现

但是,页脚是从Razor视图动态呈现的,我不希望将其存储在磁盘上的临时文件中并使用该路径,但我希望使用已在内存中呈现的HTML。通过写入
StandardInput
流,文档本身也可以这样做,如下所示:

var wkhtml = ConfigurationManager.AppSettings["WkHtmlToPdfPath"];
var p = new Process();

p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = wkhtml;

p.StartInfo.Arguments = "-q -n --disable-smart-shrinking - -";
p.Start();

var stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(template);
stdin.Dispose();
是否可以对页眉和页脚HTML执行相同的操作,即以内联方式传递它,而不必求助于临时文件

我试过:

stdin.Write(string.Format("--footer-html {0} ", footer));
但当然,它只是将其视为文档的一部分,而不是页脚

我想动态呈现页脚和页眉的主要原因是(大部分)由另一个问题引起的。虽然有一个动态的页眉和页脚会很好,但主要是为了解决我必须用一个绝对路径(即:C:\templates\images\logo.png)链接到图像的问题,因为相对路径(即:images/logo.png)在使用stdin时不起作用,只需传入一个HTML字符串块,所以我需要在运行时通过Razor插入绝对路径

对于此问题,我已尝试将进程的工作目录设置为与相对路径匹配,但无效:

p.StartInfo.WorkingDirectory = @"C:\templates";

如果我能解决这个问题,那也能解决90%的问题。

请注意,如果你解决了这个问题,朱利安,我也会假设你在MVC(?) 如果没有,您可以忽略下面的一些初始代码,但我有一个类似的情况,即我需要将输出直接流式传输到wkhtmltopdf,因为安全性和登录到站点的部分

首先,在控制器中,您可以使用任何适用的母版页(其本身可能使用页眉和页脚)拉入显示所需的视图:

然后,使用任何必要的ViewData、Tempdata等获取此视图的当前视图,并将其存储在字符串中(以下内容):

在此阶段,如果需要,您可以实际修改字符串中的输出html-例如,将任何本地路径更改为完整路径

输出HTML后,只需将其传递到wkhtmltopdf:

var p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
//Other parameters as required
byte[] file;
try
{
    p.Start();
    byte[] buffer = new byte[32768];

    using (System.IO.StreamWriter stdin = p.StandardInput)
    {
        stdin.AutoFlush = true;
        stdin.Write(content);
    }


    using (MemoryStream ms = new MemoryStream())
    {
        ms.Position = 0;
        p.StandardOutput.BaseStream.CopyTo(ms);
        file = ms.ToArray();
    }

    p.StandardOutput.Close();
    // wait or exit
    p.WaitForExit(60000);

    // read the exit code, close process
    int returnCode = p.ExitCode;

}

然后,您将拥有一个字节数组,其中包含整个页面的PDF内容

我也遇到过同样的问题,但由于Wkhtmltopdf的页眉/页脚是分开的(通过外部路径/url),我最终定义了一个html文档,并将动态数据反馈到它的url中。然后我用一些javascript提取了它们。谢谢你提供的信息。我最终并没有解决这个问题,而是使用了Microsoft RDLC报告,尽管编辑报告时相当笨拙,但它有许多优点(简单,原生打印支持)。
string content;
ViewData.Model = model;
using (var writer = new System.IO.StringWriter())
{
    var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
    view.View.Render(context, writer);
    writer.Flush();
    content = writer.ToString();
    writer.Close();
}
var p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
//Other parameters as required
byte[] file;
try
{
    p.Start();
    byte[] buffer = new byte[32768];

    using (System.IO.StreamWriter stdin = p.StandardInput)
    {
        stdin.AutoFlush = true;
        stdin.Write(content);
    }


    using (MemoryStream ms = new MemoryStream())
    {
        ms.Position = 0;
        p.StandardOutput.BaseStream.CopyTo(ms);
        file = ms.ToArray();
    }

    p.StandardOutput.Close();
    // wait or exit
    p.WaitForExit(60000);

    // read the exit code, close process
    int returnCode = p.ExitCode;

}