如何使用 GhostScript 在 ASP.NET Web应用程序中显示PDF

junwong 发布于 2012/07/19 11:29
阅读 4K+
收藏 30
原来是以为在Web应用程序中显示PDF是很难的一件事,但现在我可以告诉你们,解决这个问题只需要5分钟的时间。
以下这个范例就是一个简单的 ASP.NET 程序,包含一个网页以及一个 IHttpHandler来显示图片,为了让范例尽可能简单,我这边只用了纯粹的服务器端代码而不使用任何浏览器客户端代码。

开始

首先你将需要 Cyotek.GhostScript Cyotek.GhostScript.PdfConversion.zip 

定位 gsdll32.dll
为了能让程序正常运行, gsdll32.dll需要放置在你的应用程序路径下。可能在你的Windows 32位系统的 system32文件夹,也可能在Windows 64位系统的 SysWOW64文件夹。

当在开发过程中,我总是让网站根目录下的bin目录存放这个dll文件。当然因为我测试本范例时都是使用自己的机器,所以在IIS的Full Trust信任级别下是正常运行的,但是可不保证在 Medium Trust或者更低的信任级别下能正常工作。

必须运行在 64 位 Windows 系统
你有如下选择:
创建与64位系统对应的 GhostScript.dll. 
使用IIS7.0或更高的版本

创建解决方案
1,先创建一个 ASP.NET Web应用程序。然后打开 Default.aspx 添加以下代码

<%@ Page Language="C#" AutoEventWireup="true" 
   CodeBehind="Default.aspx.cs" Inherits="GhostScriptWebTest._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>PDF Conversion Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>
            <asp:LinkButton runat="server" ID="previousLinkButton" 
               Text="Previous" OnClick="previousLinkButton_Click" />
            <asp:LinkButton runat="server" ID="nextLinkButton" 
               Text="Next" OnClick="nextLinkButton_Click" />
        </p>
        <p>
            <asp:Image runat="server" ID="pdfImage" 
               ImageUrl="~/PdfImage.ashx?fileName=sample.pdf&page=1" />
        </p>
    </div>
    </form>
</body>
</html>


整段代码应该很好理解,唯一有意思的就是那个 pdfImage 的Image控件,此控件会调用一个Http handler,也就是我下一部分将讲解的内容。

请注意到 pdfImage 控件是指向到一个 sample.pdf 文件的,所以你在向网站的根目录添加任意pdf文件时请确保pdf文件的 Build Action 被设置为 Content,否则会无效。

创建 Image handler
如何配合IHttpHandler创建图像处理的问题你在网络上可以找到一大堆技术文章,所以我这里就不多说了。注意我下面的代码是以添加了 GhostScript.dll 作引用为前提的。
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
using Cyotek.GhostScript.PdfConversion;

namespace GhostScriptWebTest
{
  public class PdfImage : IHttpHandler
  {
    public void ProcessRequest(HttpContext context)
    {
      string fileName;
      int pageNumber;
      Pdf2Image convertor;
      Bitmap image;

      fileName = context.Server.MapPath("~/" + context.Request.QueryString["fileName"]);
      pageNumber = Convert.ToInt32(context.Request.QueryString["page"]);

      // convert the image
      convertor = new Pdf2Image(fileName);
      image = convertor.GetImage(pageNumber);

      // set the content type
      context.Response.ContentType = "image/png";

      // save the image directly to the response stream
      image.Save(context.Response.OutputStream, ImageFormat.Png);
    }

    public bool IsReusable
    { get { return true; } }
  }
}


恩,这也是一段很简单的代码。先通过查询字符串来提取pdf的文件名以及页码索引,然后创建一个Pdf2Image的对象,从pdf文件的指定页中获取图像。
接下来,你需要设置Response的 ContentType对象来让浏览器知道该如何处理。最后我们将图片的流对象直接存储到 Response的 OutputStream属性中。

简单的导航
现在我们能显示PDF了,但是还需要一些基本的导航。打开 Default.aspx.cs 然后添加以下代码
using System;
using System.Collections.Specialized;
using System.Web;
using Cyotek.GhostScript.PdfConversion;

namespace GhostScriptWebTest
{
  public partial class _Default : System.Web.UI.Page
  {
    protected void previousLinkButton_Click(object sender, EventArgs e)
    {
      this.IncrementPage(-1);
    }

    protected void nextLinkButton_Click(object sender, EventArgs e)
    {
      this.IncrementPage(1);
    }

    private void IncrementPage(int increment)
    {
      NameValueCollection queryString;
      int pageNumber;
      string pdfFileName;
      Pdf2Image converter;

      queryString = HttpUtility.ParseQueryString(pdfImage.ImageUrl.Substring(pdfImage.ImageUrl.IndexOf("?")));
      pdfFileName = queryString["fileName"];
      pageNumber = Convert.ToInt32(queryString["page"]) + increment;
      converter = new Pdf2Image(this.Server.MapPath("~/" + pdfFileName));

      if (pageNumber > 0 && pageNumber <= converter.PageCount)
        pdfImage.ImageUrl = string.Format("~/PdfImage.ashx?fileName={0}&page={1}", pdfFileName, pageNumber);
    }
  }
}


很明显,只需要通过更改页码我们就能得到需要的成果了。

原文链接 , OSChina.NET 原创翻译
加载中
0
Echo
Echo

不太理解这个方案的意义,

1.在浏览器中打开pdf文件?

//直接提供PDF文件下载功能即可,浏览器自带对了PDF的打开和查阅工具

2.将PDF转换为一张张的图片在WEB中显示?

junwong
junwong
1,你说的虽然可以,但是麻烦了,用户可能打开网页就能看到 2,对,就是这个意思
0
CoserSeu
CoserSeu

直接打开PDF是好,但如果这样的话,很大程度是资源保密性就不好了,谁都能下到原版。

一般的做法是用flash来做,需要embed,还要actionscript和javascript交互,挺繁琐的,楼主的方法不错。不知道有没有java的?

0
廖斌

尝试了下,没有 gsdll32.dll ,网上下载的几个貌似版本不对,提示

“无法在 DLL“gsdll32.dll”中找到名为“gsapi_new_instance”的入口点。”

0
kimmking
kimmking
icepdf不是很好么
0
r
redy0816
win7下实验不成功
返回顶部
顶部