【问题标题】:Print pdf document from MemoryStream从 MemoryStream 打印 pdf 文档
【发布时间】:2013-01-17 23:11:26
【问题描述】:

我需要打印一个我已更改的 pdf 文档,但不将其保存为新的 pdf 文档。下面的代码可以正常工作。但是,我想以完全不同的方式做到这一点,并且我同时有大脑滞后并且看不到解决方案。

我的代码示例

byte[] result;

using (MemoryStream ms = new MemoryStream())
{
    PdfReader pdfReader = new PdfReader("c:\\templatePdf.pdf");
    PdfStamper pdfStamper = new PdfStamper(pdfReader, ms);

    /* abbreviated but here I alter the template pdf */

    pdfStamper.FormFlattening = true;
    pdfStamper.Close();
    result = ms.GetBuffer();
}

/* Instead of saving a new file I would rather like to print
   the altered template pdf in memory and then discard it */
using (FileStream fs = File.Create("C:\\Test.pdf"))
{
    fs.Write(result, 0, (int)result.Length);
}

Process process = new Process();
process.StartInfo.FileName = "C:\\Test.pdf";
process.StartInfo.Verb = "printto";
process.StartInfo.Arguments = "\"" + ppr_PrinterDropDown.Text + "\"";
process.Start();
File.Delete("C:\\Test.pdf");

【问题讨论】:

  • 你应该使用result = ms.GetBuffer() - 你应该使用ToArray()。否则你会有一堆尾随空值。此外,使用File.WriteBytes 或仅使用MemoryStream.WriteTo 让生活更简单。
  • 感谢您的评论@JonSkeet,但我将如何在进程中处理它而进程需要读取文件名? (我的意思是这样我可以打印 pdf);)
  • 这并不是一个答案——它只是围绕现有代码的一个旁白。根据 Marc 的回答,我怀疑您仍然需要使用文件。
  • 是的,你们俩可能都是对的。感谢您的 cmets :)
  • 我一直在研究类似的东西(更新 pdf 表单然后打印,而不将中间文件保存到磁盘)。你有没有想过没有磁盘写入的打印方法?似乎答案会导致作为一种选择,但我想我会问。

标签: c# pdf itextsharp


【解决方案1】:

如果您使用的是基于文件的 API,那么在没有文件的情况下您将很难做到。您可能能够设置命名管道服务器,但坦率地说,这是一个巨大的小提琴。但是,我很想四处寻找具有打印支持的完全托管的 PDF 库。但最终......文件系统有什么危害,真的?可能不会很多。不过,我可能建议一些调整:

  1. 使用临时区域 (Path.GetTempPath()),而不是 C:\Test
  2. 在删除文件之前等待该过程完成

【讨论】:

  • 感谢您的回答@MarcGravell。那可能是唯一的方法,至少我目前无法找到任何解决方案。我可能会寻找一些 pdf 库来帮助我解决问题,但我想我会采取简单的方法,只使用临时位置:)
【解决方案2】:

首先我们需要写入内存流,然后在内存流方法“WriteTo”的帮助下,我们可以写入页面的响应,如下面的代码所示。

   MemoryStream filecontent = null;
   filecontent =//CommonUtility.ExportToPdf(inputXMLtoXSLT);(This will be your MemeoryStream Content)
   Response.ContentType = "image/pdf";
   string headerValue = string.Format("attachment; filename={0}", formName.ToUpper() + ".pdf");
   Response.AppendHeader("Content-Disposition", headerValue);

   filecontent.WriteTo(Response.OutputStream);

   Response.End();

FormName 是给定的文件名,此代码将通过调用 PopUp 使生成的 PDF 文件可下载。

【讨论】:

  • “页面响应”是什么意思? “响应”来自什么方法?
【解决方案3】:

这很容易。困难的部分是获取有关打印状态完成和总页码的有用信息。

var pq = LocalPrintServer.GetDefaultPrintQueue();
var theJob = pq.AddJob();
try{
    using(var js = theJob.JobStream){
        var buffer = File.ReadAllBytes("yourPathToPdf");
        js.Write(buffer,0,buffer.Length);
    }
    var done=false;
    while(!done)
    {
        pq.Refresh();
        theJob.Refresh();
        done = theJob.IsCompleted || theJob.IsDeleted || theJob.IsPrinted;
    }
}
catch(Exception ex){
    //handle this
}
finally{
    theJob?.Dispose();
    pq?.Dispose();
}

当然,这是假设您的打印机支持原生 PDF。否则,您将不得不自己在客户端上完成渲染工作,并且不能将其作为原始流发送。

【讨论】:

  • 感谢您的评论,尽管该线程实际上已经很老了 :) 当我得到更改并给您反馈时,我可能会尝试一下。
猜你喜欢
  • 2010-10-12
  • 2016-10-09
  • 2019-08-16
  • 2011-08-01
  • 2018-06-13
  • 2020-06-10
  • 1970-01-01
  • 2013-07-06
  • 2011-05-26
相关资源
最近更新 更多