Spiga

使用HttpHandler解析并展示PDF文档内容

2009-03-11 11:08 by LanceZhang, 2685 visits, 网摘, 收藏, 编辑

前言

如果我们想将服务端的PDF文档内容展示给客户端,往往会通过URL直接访问的方式。这样一来,PDF文档就会毫无保留的保存到客户端去,通过浏览器的PDF插件,客户端可以随意拷贝PDF的副本。(如下图)

本文通过HttpHandler和开源控件PDFBox来对PDF文档进行访问控制,只向客户端解析并展示PDF的内容而非PDF文件本身。

 

PDF解析

目前有许多PDF解析组件,国内比较常用的是iTextSharp,该控件早期从JAVA移植过来,完全支持.NET平台,在创建PDF文档方面非常灵活易用。然而在读取解析PDF时却显得力不从心,只有少数复杂难用的类可以让我们读取PDF。故不适合本案。

PDFBox在此方面表现却非常突出,同样,它也是从java平台移植过来的, 常用来作为Lucene的PDF索引器。目前,它的开源项目中已经包含了通过IKVM.NET(IKVM.NET is an implementation of Java for Mono and the Microsoft .NET Framework.)封装,而支持.NET的组件。

PDFBox对PDF的读取解析非常简单,只用如下代码即可完成:

private static string parseUsingPDFBox(string filename)
{
    PDDocument doc 
= PDDocument.load(filename);
    PDFTextStripper stripper 
= new PDFTextStripper();
    
return stripper.getText(doc);
}

 

故我们选取PDFBox作为PDF解析器。

 

编写HttpHandler

接下来,我们新建一个类库项目,在其中创建PDFHandler类,实现IHttpHandler接口,用来作为.pdf文件的handler。

主要完成的步骤如下:

1. 为类库和网站添加如下引用:

  • PDFBox-0.7.2.dll
  • IKVM.GNU.Classpath.dll

   并将下面两个类库也复制到网站的Bin文件夹中:

  • FontBox-0.1.0-dev.dll
  • IKVM.Runtime.dll

2. 编写PDFHandler类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using org.pdfbox.pdmodel;
using org.pdfbox.util;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.IO;

namespace LanceZhang.HTTP
{
    
public class PDFHandler:IHttpHandler
    {
        
#region IHttpHandler Members

        
public bool IsReusable
        {
            
get { return true; }
        }

        
public void ProcessRequest(HttpContext context)
        {
            
//获取请求的文件路径,如C:\www\a.pdf
            string path = context.Request.MapPath(context.Request.Path);

            
//创建PDF实体和文字解析器
            PDDocument doc = PDDocument.load(path);
            PDFTextStripper stripper 
= new PDFTextStripper();

            
//创建一个TextBox用来显示PDF内容
            TextBox tb = new TextBox();

            tb.Style.Add(
"width","100%");
            tb.Style.Add(
"height""100%");

            tb.TextMode 
= TextBoxMode.MultiLine;
            tb.Text
=stripper.getText(doc);

            
//将TextBox render出来
            context.Response.Write(RenderControlAsString(tb));
        }

        
public string RenderControlAsString(Control ctl)
        {
            StringWriter sw 
= new StringWriter();
            HtmlTextWriter writer 
= new HtmlTextWriter(sw);
            ctl.RenderControl(writer);
            
return sw.ToString();
        }


        
#endregion
    }
}

 

部署HttpHandler

1.  编码完成后,我们编译Handler类库项目,并添加网站对该项目的引用。

2.  要使客户端对*.pdf文件的请求被handler处理,我们还需要在web.config中配置刚刚编写好的handler:

<system.web>
    
<httpHandlers>
      
<add verb="*" path="*.pdf" type="LanceZhang.HTTP.PDFHandler,LanceZhang.HTTP"/>
    
</httpHandlers>
</system.web>

 

3. 这时,使用Visual Studio自带的ASP.NET Deployment Server已经可以成功运行程序了。然而,如果将网站部署到IIS中,我们还需要对IIS的应用程序配置做出修改,在程序映射中,使用aspnet_isapi.dll来处理.pdf文件:

 

OK,接下来启动IIS,浏览“CardSpace.pdf”文件,我们就可以得到下面的效果:

 

下载PDFBox类库

download the PDFBox package

 


作者:Lance ZhangLance Zhang's Tech Blog
出处:http://blodfox777.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

0
0
(请您对文章做出评价)
« 上一篇:ASP.NET AJAX Advance Tips & Tricks (8) 扩展AJAX Control Toolkit中的控件
» 下一篇:将cnblogs嵌入你的Visual Studio 2005/2008
Add your comment

30 条回复

  1. #1楼 张蒙蒙      2009-03-11 11:15
    很实用,感谢分享
      回复  引用  查看    
  2. #2楼 lt1[未注册用户]2009-03-11 11:20
    经典,为了不被保存服务端PDF而直接输出文字的做法实在令人叹为观止,佩服,LZ提供的PDF解析控件很不错。
      回复  引用    
  3. #3楼 !A.Z[未注册用户]2009-03-11 11:20
    IKVM.............
      回复  引用    
  4. #4楼 ★金★      2009-03-11 11:25
    如果有图片可以解析吗?
      回复  引用  查看    
  5. #5楼[楼主] LanceZhang      2009-03-11 11:30
    @lt1
    @张蒙蒙
    谢谢支持,过奖了
      回复  引用  查看    
  6. #6楼[楼主] LanceZhang      2009-03-11 11:33
    @★金★

    不可以直接提取出来的,但是pdfbox支持把pdf文件转换成图片
      回复  引用  查看    
  7. #7楼 ★金★      2009-03-11 11:54
    能否显示HTML格式的,因为这样显示不易阅读。
      回复  引用  查看    
  8. #8楼[楼主] LanceZhang      2009-03-11 12:00
    @★金★
    当然可以,在ProcessRequest中处理即可
      回复  引用  查看    
  9. #9楼 拓荒者      2009-03-11 12:44
    context.Response.Write("<pre>"+stripper.getText(doc)+"</pre>");
    是不是更简单点
      回复  引用  查看    
  10. #10楼 Aaron Wu      2009-03-11 12:47
    下了试试再给反馈,占位
      回复  引用  查看    
  11. #11楼 rayZ[未注册用户]2009-03-11 12:53
    请问能把网页导出到PDF吗?
      回复  引用    
  12. #12楼 yuchen[未注册用户]2009-03-11 13:22
    我很感兴趣博主的图片是怎么做出来的?
    用什么可以做出撕纸效果的
      回复  引用    
  13. #13楼 Aaron Wu      2009-03-11 13:34
    --引用--------------------------------------------------
    yuchen: 我很感兴趣博主的图片是怎么做出来的?
    用什么可以做出撕纸效果的
    --------------------------------------------------------
    PS?
      回复  引用  查看    
  14. #14楼 ★金★      2009-03-11 13:58
    @LanceZhang
    能否告知如何把PDF装为图片,能不能给些代码提示?
      回复  引用  查看    
  15. #15楼[楼主] LanceZhang      2009-03-11 14:01
    @yuchen
    @Aaron Wu
    用SnagIt32.exe抓的
      回复  引用  查看    
  16. #16楼 jowo      2009-03-11 14:01
    是不是把pdf的内容显示到TextBox里去呢?
    如果这样一样被客户拷走呀?这样有啥意思呢?
      回复  引用  查看    
  17. #17楼[楼主] LanceZhang      2009-03-11 14:02
    @★金★
    这个我没有现成的代码,但网上例子比较多“pdfbox pdftoimage”
      回复  引用  查看    
  18. #18楼[楼主] LanceZhang      2009-03-11 14:02
    --引用--------------------------------------------------
    rayZ: 请问能把网页导出到PDF吗?
    --------------------------------------------------------
    可以,但一般用iTextSharp来做这件事情
      回复  引用  查看    
  19. #19楼 jowo      2009-03-11 14:04
    要是能做成豆丁网那种,那就真的拷不走了
      回复  引用  查看    
  20. #20楼[楼主] LanceZhang      2009-03-11 14:37
    @jowo
    哦,它是嵌到flash里了吧,那可真没办法
      回复  引用  查看    
  21. #21楼 by elwinTest[未注册用户]2009-03-11 15:05
    很好.学习了!正好用到项目中去.
      回复  引用    
  22. #22楼 1231[未注册用户]2009-03-11 17:29
    @yuchen
    很多截图软件都支持啊!
      回复  引用    
  23. #23楼 atian15leo[未注册用户]2009-03-17 15:24
    错误 1 未能加载文件或程序集“IKVM.GNU.Classpath”或它的某一个依赖项。无法验证强名称签名。此程序集可能已被篡改,或者已被延迟签名,但没有用正确的私钥进行完全签名。 (异常来自 HRESULT:0x80131045)
      回复  引用    
  24. #24楼 更好的工作2009-03-17 18:20
    杭州某产品IT 公司正在招.NET 产品分析师,.NET 产品架构师,是ERP 相关产品,不要求英文。 待遇不错。 合适者请速与我联系,谢谢! anna@top-talent.com.cn (满好的工作机会,请不要删我,重谢!)
      回复  引用    
  25. #25楼[楼主] LanceZhang      2009-03-18 09:31
    --引用--------------------------------------------------
    更好的工作: 杭州某产品IT 公司正在招.NET 产品分析师,.NET 产品架构师,是ERP 相关产品,不要求英文。 待遇不错。 合适者请速与我联系,谢谢! anna@top-talent.com.cn (满好的工作机会,请不要删我,重谢!)
    --------------------------------------------------------

    不要求英文走不远啊...
      回复  引用  查看    
  26. #26楼[楼主] LanceZhang      2009-03-18 09:32
    @atian15leo
    是IKVM程序集的问题,应该是没引用好
      回复  引用  查看    
  27. #27楼 ★金★      2009-04-02 13:46
    只能解析文本,如果可以解析图片就好了。
      回复  引用  查看    
  28. #28楼 不若相忘于江湖      2009-06-12 10:59
    这个文章好像在哪看过。。

    以前在首页。
      回复  引用  查看    
  29. #29楼[楼主] LanceZhang      2009-06-12 12:47
    @不若相忘于江湖
    以前吗?有人琢磨的跟偶一样?那好巧,其实也只算是个tick,没什么实际意义,偶看asp.net advanced topics时突然冒出的想法
      回复  引用  查看    
  30. #30楼 RubyPDF      2009-06-19 11:15
    .net 版本的PDFBox恐怕还不能支持PDF转Image
      回复  引用  查看