我在我的开发机器上开发了一个解决方案:
- 通过C打开文件路径服务器端的PDF#
- 将它们合并在一起
Response.BinaryWrite
将合并后的PDF推送到浏览器
在本地DEV上效果很好。当推送到服务器时,它会在浏览器窗口中得到一些"二进制胡言乱语"。
Adobe或Foxit阅读器没有安装在服务器上,但它安装在我的本地开发机器上。我的理解是iTextSharp允许你根本不需要安装PDF阅读器,但它是吗?或者这可能是IIS的事情,其中.pdf没有被列为文件类型。。。
以下是一些示例代码:
// First set up the response and let the browser know a PDF is coming
context.Response.Buffer = true;
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("Content-Disposition", "inline");
List<string> PDFs = new List<string>();
PDFs.Add(@"c:usersshanedocumentsvisual studio 2010ProjectsPDFMultiPrintTesterPDFMultiPrintTesterTEST1.pdf");
PDFs.Add(@"c:usersshanedocumentsvisual studio 2010ProjectsPDFMultiPrintTesterPDFMultiPrintTesterTEST2.pdf");
PDFs.Add(@"c:usersshanedocumentsvisual studio 2010ProjectsPDFMultiPrintTesterPDFMultiPrintTesterTEST3.pdf");
// Second, some setup stuff
System.IO.MemoryStream MemStream = new System.IO.MemoryStream();
iTextSharp.text.Document doc = new iTextSharp.text.Document();
iTextSharp.text.pdf.PdfReader reader = default(iTextSharp.text.pdf.PdfReader);
int numberOfPages = 0;
int currentPageNumber = 0;
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, MemStream);
doc.Open();
iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
iTextSharp.text.pdf.PdfImportedPage page = default(iTextSharp.text.pdf.PdfImportedPage);
int rotation = 0;
foreach (string f in PDFs)
{
// Third, append all the PDFs--THIS IS THE MAGIC PART
byte[] sqlbytes = null;
sqlbytes = ReadFile(f);
reader = new iTextSharp.text.pdf.PdfReader(sqlbytes);
numberOfPages = reader.NumberOfPages;
currentPageNumber = 0;
while ((currentPageNumber < numberOfPages))
{
currentPageNumber += 1;
doc.SetPageSize(PageSize.LETTER);
doc.NewPage();
page = writer.GetImportedPage(reader, currentPageNumber);
rotation = reader.GetPageRotation(currentPageNumber);
if ((rotation == 90) | (rotation == 270))
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(currentPageNumber).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
}
// Finally Spit the stream out
if (MemStream == null)
{
context.Response.Write("No Data is available for output");
}
else
{
doc.Close();
context.Response.BinaryWrite(MemStream.GetBuffer());
context.Response.End();
MemStream.Close();
}
}
}
public static byte[] ReadFile(string filePath)
{
byte[] buffer;
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read
// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
sum += count; // sum is a buffer offset for next reading
}
finally
{
fileStream.Close();
}
return buffer;
}
我的理解是iTextSharp允许您不需要PDF读卡器安装了,但它安装了吗?
iTextSharp用于生成PDF文件。这与浏览这些文件的方式无关。如果您的客户端机器上没有安装PDF阅读器,该阅读器正在浏览响应中流式传输此PDF文件的应用程序,请不要期望在该客户端机器上收到除胡言乱语之外的任何其他内容。
不幸的是,您还没有在服务器上显示用于生成此PDF文件的代码,因此很难说问题是否与此有关。重要的是将响应的ContentType设置为application/pdf
,并向响应发送一个有效的PDF文件。在客户端上解释此响应的方式将在很大程度上取决于所使用的浏览器以及此客户端机器上安装的不同插件和PDF阅读器。
您可能需要将Response.ContentType
设置为application/pdf
。参见相关SO帖子。
当你渲染Content-Disposition: inline
时,它会在IE中使用Adobe插件-"Adobe PDF链接帮助程序"(或FoxIt Reader)。由于你的服务器上可能没有这个ActiveX插件(AcroIEHelperShim.dll
),它只会将字节内容内联渲染为text/html
,因为它没有内联解释器。
终于想通了。您不需要在服务器上安装Adobe PDF阅读器或Foxit阅读器。您只需要在服务器上安装iTextReader(我所说的已安装是指程序集存在于您的解决方案中)。您需要的是IIS中的MIME类型。我们必须添加MIME类型,然后它马上就起作用了。有趣的是,即使有了这些,Chrome也能正确地处理并渲染它。我假设IIS放置了与该MIME类型相关联的适当标头,但这并没有发生。IE8搞不清楚。