无需Acrobat的PDF查看器实现

在本文中,将探讨如何在不依赖Adobe Acrobat软件的情况下,使用ASP.NET技术实现一个PDF查看器。这个查看器能够读取PDF文档的页面,将其转换为PNG格式的图像,并在网页上显示。将详细介绍实现这一功能所需的基本概念、代码实现以及配置要求。

基本概念

要实现PDF查看器,首先需要获取PDF文档的总页数,以确定页面的边界。然后,将选择特定的页面并将其转换为光栅图像格式,如PNG。为此,将使用PdfLibNet和XPDF库。以下是实现过程中涉及的关键步骤:

  • 获取PDF文档的页数。
  • 将选定的PDF页面转换为PNG文件。
  • 在网页上显示PNG文件。

工具类介绍

为了实现上述功能,创建了一些工具类,它们提供了从各种辅助库中所需的功能。这些类包括:

  • AFPDFLibUtil.vb:包含创建书签HTML、搜索、获取页数、将PDF转换为PNG的方法。
  • ImageUtil.vb:包含图像操作的方法,如调整大小、旋转、转换等。
  • ASPPDFLib.vb:包含调用特定技术的通用包装函数。
  • PDFViewer.ascx.vb:包含PDF查看器用户控件的代码。
  • PDFViewer.ascx:包含PDF查看器用户控件的客户端HTML/JavaScript。

代码使用

要使用这个PDF查看器,需要对ASP服务器进行一些配置。以下是配置要求:

  • 确保ASPNET用户(IISUSR、ASPNET或网络服务用户)有权限修改/PDF和/render目录。
  • 确保ASPNET用户有权限读取和执行/bin目录。
  • 确保PDFLibNet.dll可用,并且可能需要将其注册到GAC中。
  • 确保PDFLibNet.dll和PDFLibCmdLine.exe都编译为相同的架构(x86或x64)。
  • 如果使用x86,并且操作系统是64位的,需要设置应用程序池的高级设置以允许执行32位应用程序。

放置PDF查看器用户控件

要在网页上放置PDF查看器用户控件,可以使用以下ASP.NET代码:

<uc1:PDFViewer ID="PDFViewer1" runat="server" />

在代码后台设置FileName属性以查看PDF文件:

Dim pdfFileName As String = Request.MapPath("PDF") & "\myPDF.pdf" If ImageUtil.IsPDF(pdfFileName) Then ErrorLabel.Visible = False PDFViewer1.FileName = pdfFileName Else ErrorLabel.Text = "Only PDF files (*.pdf) are allowed to be viewed." ErrorLabel.Visible = True End If

关键实现

解决方案的核心是从PDF文件中提取当前要查看的页面。由于使用的是ASP.NET,选择实现基于文件的解决方案,以避免在尝试持久化PDF字节流时出现内存管理问题。选择使用PDFLibNet提取PDF页面,并将其存储到文件系统中作为PNG图像。选择PNG,因为它使用ZIP压缩,结果是无损压缩的图像和较小的文件大小。

代码示例

以下是使用PDFLibNet从PDF中获取页面并转换为PNG的代码示例:

Public Shared Function GetPageFromPDF(ByVal filename As String, ByVal destPath As String, ByRef PageNumber As Integer, Optional ByVal DPI As Integer = RENDER_DPI, Optional ByVal Password As String = "", Optional ByVal searchText As String = "", Optional ByVal searchDir As SearchDirection = 0) As String GetPageFromPDF = "" Dim pdfDoc As New PDFLibNet.PDFWrapper pdfDoc.RenderDPI = 72 pdfDoc.LoadPDF(filename) If Not Nothing Is pdfDoc Then pdfDoc.CurrentPage = PageNumber pdfDoc.SearchCaseSensitive = False Dim searchResults As New List(Of PDFLibNet.PDFSearchResult) If searchText <> "" Then Dim lFound As Integer = 0 If searchDir = SearchDirection.FromBeginning Then lFound = pdfDoc.FindFirst(searchText, _ PDFLibNet.PDFSearchOrder.PDFSearchFromdBegin, False, False) ElseIf searchDir = SearchDirection.Forwards Then lFound = pdfDoc.FindFirst(searchText, _ PDFLibNet.PDFSearchOrder.PDFSearchFromCurrent, False, False) ElseIf searchDir = SearchDirection.Backwards Then lFound = pdfDoc.FindFirst(searchText, _ PDFLibNet.PDFSearchOrder.PDFSearchFromCurrent, True, False) End If If lFound > 0 Then If searchDir = SearchDirection.FromBeginning Then PageNumber = pdfDoc.SearchResults(0).Page searchResults = GetAllSearchResults(filename, searchText, PageNumber) ElseIf searchDir = SearchDirection.Forwards Then If pdfDoc.SearchResults(0).Page > PageNumber Then PageNumber = pdfDoc.SearchResults(0).Page searchResults = GetAllSearchResults(filename, searchText, PageNumber) Else searchResults = SearchForNextText(filename, searchText, _ PageNumber, searchDir) If searchResults.Count > 0 Then PageNumber = searchResults(0).Page End If End If ElseIf searchDir = SearchDirection.Backwards Then If pdfDoc.SearchResults(0).Page < PageNumber Then PageNumber = pdfDoc.SearchResults(0).Page searchResults = GetAllSearchResults(filename, searchText, PageNumber) Else searchResults = SearchForNextText(filename, searchText, _ PageNumber, searchDir) If searchResults.Count > 0 Then PageNumber = searchResults(0).Page End If End If End If End If End If Dim outGuid As Guid = Guid.NewGuid() Dim output As String = destPath & "\" & outGuid.ToString & ".png" Dim pdfPage As PDFLibNet.PDFPage = pdfDoc.Pages(PageNumber) Dim bmp As Bitmap = pdfPage.GetBitmap(DPI, True) bmp.Save(output, System.Drawing.Imaging.ImageFormat.Png) bmp.Dispose() GetPageFromPDF = output If searchResults.Count > 0 Then GetPageFromPDF = HighlightSearchCriteria(output, DPI, searchResults) End If pdfDoc.Dispose() End If End Function
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485