使用Process()将输入流写入另一个流
本文关键字:另一个 输入流 Process 使用 | 更新日期: 2023-09-27 18:11:12
我正在编写一个程序,该程序需要接受一个输入流,然后将其通过一个进程,然后输出一个新的流。这是用于使用由xml和xsl组成的流,并通过wkhtmltopdf.exe将其转换为pdf,并将pdf作为流输出。如有任何帮助,不胜感激。
编辑以添加代码和更好的理解:
进入函数我发送一个MemoryStream作为参数,我返回字节[]。我目前的代码看起来像这样,但它没有功能,因为我试图弄清楚如何接受流输入,转换它,然后再次返回它作为一个新的流。
code
public byte[] WKHtmlToPdf(MemoryStream inputStream)
{
var fileName = " - ";
_workingDirectory = ""; ''there is a directory here but contains company name
''so I removed it
_wkhtmlexe = wkhtmltopdf.exe";
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 = _wkhtmlexe;
p.StartInfo.WorkingDirectory = _workingDirectory;
StreamWriter inpuStreamWriter = new StreamWriter(inputStream);
inpuStreamWriter = p.StandardInput;
StreamReader outpStreamReader = p.StandardOutput;
string switches = "";
switches += "--print-media-type ";
switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm ";
switches += "--page-size Letter ";
p.StartInfo.Arguments = switches + " " + inputStream + " " + fileName;
p.Start();
inpuStreamWriter.Write();
//read output
byte[] buffer = new byte[32768];
byte[] file;
using (var ms = inputStream)
{
while (true)
{
int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
ms.Write(buffer, 0, read);
}
file = ms.ToArray();
}
// wait or exit
p.WaitForExit(60000);
// read the exit code, close process
int returnCode = p.ExitCode;
p.Close();
return returnCode == 0 ? file : null;
}
您使用process的方法有部分错误。您可以从现有的html文件创建新的pdf文件,但您必须使用两个临时文件(一个用于html,第二个用于pdf输出)。在此场景中,工作流程将是:1)将记忆流保存为临时html文件2)运行新的进程(没有流重定向)-它产生新的PDF文件3)返回新的pdf文件作为流4)清理临时文件一旦你完成
或
你可以使用PInvoke直接使用libwkhtmltox
或(最好的)
你可以使用现有的解决方案,例如Pechkin,它为你做所有的PInvoke和本地合作与libwkhtmltox库:Pechkin使用
找到了解决问题的方法
private static void GeneratePdfFromStream()
{
var ms = xml_and_xsl_to_html();
File.WriteAllBytes(Constants.FilesResultHtml, ms.ToArray());
var printer = new Printer();
var pdfStream = printer.GeneratePdf(new StreamReader(ms, Encoding.GetEncoding(850), false));
File.WriteAllBytes(Constants.FilesResultPdf, pdfStream.ToArray());
}
变量ms是从XslCompiledTransform()函数返回的内存流。然后将其传递给编码页850的streamReader中的GeneratePdf。函数看起来像这样:
public MemoryStream GeneratePdf(StreamReader html)
{
html.BaseStream.Position = 0;
var pdf = new MemoryStream();
using (html)
{
Process p;
var psi = new ProcessStartInfo
{
FileName = @"C:'wkhtmltopdf'wkhtmltopdf.exe",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
Arguments = Switches() + "-q -n --enable-smart-shrinking " + " - -"
};
p = Process.Start(psi);
try
{
if (p != null)
{
var stdin = p.StandardInput;
stdin.AutoFlush = true;
stdin.Write(html.ReadToEnd());
stdin.Dispose();
}
CopyStream(p.StandardOutput.BaseStream, pdf);
Console.WriteLine( p.StandardOutput.CurrentEncoding.CodePage);
p.StandardOutput.Close();
pdf.Position = 0;
p.WaitForExit(10000);
return pdf;
}
catch
{
return null;
}
finally
{
if (p != null) p.Dispose();
}
}
}