65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 ASP.NET 中压缩文件夹

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.69/5 (6投票s)

2009年4月7日

CPOL

3分钟阅读

viewsIcon

41224

解释如何在 ASP.NET 中压缩文件夹。

引言

本文解释了如何从 ASP.NET 压缩文件夹,以及客户端如何下载和保存压缩后的文件夹到本地。

背景

几个月前,在我的 ASP.NET 应用程序中,我需要使用 Crystal Reports 创建一些不同的报告,并将这些报告以 PDF 格式发送给客户端。如果我只有一个报告要显示,我可以将其显示在浏览器中,客户端可以将其保存在本地。但是,报告的数量很大,我决定将所有生成的报告放在一个动态创建的文件夹中,压缩该文件夹,并将压缩后的文件夹发送给客户端。在这里,我将解释如何实现所有这些步骤。由于您的整体需求可能有所不同,因此我没有提供完整的源代码。

我使用 Visual Studio 2005 IDE 用 VB.NET 编写了所有代码,您可以轻松地将其转换为 C#。

以 PDF 格式生成 Crystal Reports 并在浏览器中显示

以 PDF 格式生成 Crystal Reports

此代码片段解释了如何以 PDF 格式生成 Crystal Reports 报告并在客户端浏览器中显示它。我假设您已经使用 Crystal Reports 创建(设计)了一个报告。

此函数将以 PDF 格式创建报告,并将其作为内存流发送给调用者

Public Function CreatePDFStream() As MemoryStream

    Dim newConnectionInfo As ConnectionInfo = GetConnectionInfo()
    Dim report As New ReportDocument
    Dim reportPath As String = Server.MapPath(".\Reports\Myreport.rpt")
    Dim PDFStream As MemoryStream

    report.Load(reportPath, OpenReportMethod.OpenReportByTempCopy)
    SetDBLogonForReport(newConnectionInfo, report)
    SetCurrentValuesForParameterField(report)

    With report
        .ExportOptions.ExportDestinationType = _
          CrystalDecisions.Shared.ExportDestinationType.DiskFile
        .ExportOptions.ExportFormatType = _
          CrystalDecisions.Shared.ExportFormatType.PortableDocFormat
        .Refresh()
        SetCurrentValuesForParameterField(report)
        PDFStream = CType(.ExportToStream(ExportFormatType.PortableDocFormat), _
                                          MemoryStream)
        .Close()
   End With

    Return PDFStream
End Function

在上面的函数中,GetConnectionInfo 将简单地从配置文件中读取连接详细信息,并将详细信息存储在 CrystalDecisions.Shared.ConnectionInfo 中。此 ConnectionInfo 稍后由报告用于连接到服务器。这是在函数 SetDBLogonForReport 中完成的,下面将重现相同的代码。

ConnectionInfo 需要设置以下属性,代码如下所示

With newConnectionInfo
        DatabaseName = conn.Database
        ServerName = conn.Server
        UserID = conn.User
        .Password = conn.Password
End With

SetDBLogOnForReport 将为报告设置连接和数据库属性,代码如下

Private Sub SetDBLogonForReport(ByVal connectionInfo As ConnectionInfo, _
            ByVal myReportDocument As ReportDocument)
    Dim crtableLogoninfos As New TableLogOnInfos()
    Dim crtableLogoninfo As New TableLogOnInfo()
    Dim crConnectionInfo As New ConnectionInfo()

    Dim crTables As Tables
    Dim crTable As Table

       crTables = myReportDocument.Database.Tables

    For Each crTable In crTables
        crtableLogoninfo = crTable.LogOnInfo
        crtableLogoninfo.ConnectionInfo = connectionInfo
        crTable.ApplyLogOnInfo(crtableLogoninfo)
        crTable.Location = connectionInfo.DatabaseName & ".dbo." & _
                crTable.Location.Substring(crTable.Location.LastIndexOf(".") + 1)
        crTable.LogOnInfo.ConnectionInfo.ServerName = connectionInfo.ServerName()
    Next

End Sub

设置完连接详细信息后,我们需要为报告设置参数(如果有)。在我的例子中,我将从查询字符串中获取所需的参数。SetCurrentValuesForParameterField 将完成这项工作。

Private Sub SetCurrentValuesForParameterField(ByVal myReportDocument As ReportDocument)

    ProcessQueryString() 'simply extract my parameters from query string

    Dim currentFirstParameteValues As ParameterValues = New ParameterValues()
    Dim currentSecondParameterValues As ParameterValues = New ParameterValues()

    Dim FirstParameterValue As New CrystalDecisions.Shared.ParameterDiscreteValue
    Dim SecondParameterValue As New CrystalDecisions.Shared.ParameterDiscreteValue

    FristParameterValue.Value = xxxxx ' Value from the processed query string
    SecondParameterValue.Value = yyyy ' Value from the processed query string

    currentFirstParameterValues.Add(FirstParameterValue)
    currentSecondParameterValues.Add(SecondParameterValue)
        

    ' Getting info about report parameters
    Dim SSTParameterFieldDefinitions As ParameterFieldDefinitions = _
                      myReportDocument.DataDefinition.ParameterFields

    Dim FirstParameterFieldDefinition As ParameterFieldDefinition = _
                                         SSTParameterFieldDefinitions(0)
    Dim SecondParameterFieldDefinition As ParameterFieldDefinition = _
                                          SSTParameterFieldDefinitions(1)

    'providing current values for the report
    FristParameterFieldDefinition.ApplyCurrentValues(currentFirstParameterValues)
    SecondParameterFieldDefinition.ApplyCurrentValues(currentSecondParameterValues)

End Sub

在浏览器中显示 PDF 报告

在浏览器中显示 PDF 报告非常简单

PDFStream= CreatePDFStream
If Not PDFStream is nothing Then
Response.Clear()
      Response.Buffer = True
      Response.ContentType = "application/pdf"
      Response.BinaryWrite(PDFStream.ToArray())
      Response.End()
      PDFStream.Close()
End If

压缩文件夹

在解释如何压缩文件夹之前,让我解释一下如何将压缩后的文件夹定向到浏览器,以便客户端可以下载并保存它。此代码假定您知道压缩后文件夹的路径。

'fully qualified path of zipped folder
zippedFolderPath = zippath
Me.Response.Clear()
Me.Response.AddHeader("Content-Disposition", _
                      "attachment; filename=" + _
                      zippedFolderPath)
Me.Response.ContentType = "Application/X-zip-compressed"
Me.Response.WriteFile(zippedFolderPath)
Me.Response.Flush()
'Deleting zipped folder
System.IO.File.Delete(zippedFolderPath)

为了压缩文件夹,您需要添加一些命名空间。所有这些命名空间都是 Visual J# 库 vjslib.dll 的一部分。因此,首先,您需要将此库添加到应用程序中。您可以在 .NET 框架版本路径中找到此库。在我的机器上,它位于 C:\Windows\Microsoft.Net\FrameWork\V2.0.50727\vjslib.dll 中。

要导入的命名空间是

Imports java.io
Imports java.util
Imports java.util.zip

以下函数将创建单独的 PDF 报告,将它们放入新创建的文件夹中,压缩该文件夹,并向调用者返回压缩文件的名称

Private Function CreatePDFFiles() As String
    Dim outPutDirectoryName As String
    outPutDirectoryName = _outputPath + "_" + _sessionID
    createOutputDirectory(outPutDirectoryName) ‘ Create a directory
       Dim zipFileName As String = outPutDirectoryName & ".zip"
    Dim PDFStream As MemoryStream

    ' Creating individual reports 
    For Each kvp As KeyValuePair(Of Integer, String) In details
            
        PDFStream = CreatePDFStream() ‘already explained
        Dim pdfBuffer(CType(PDFStream.Length - 1, Integer)) As Byte
        PDFStream.Read(pdfBuffer, 0, pdfBuffer.Length)
        PDFStream.Close()
        Dim PDFFileName As String
        PDFFileName = outPutDirectoryName + "\" + CreateOutPutPDFFileName(code) 
        Dim PDFFile As New FileStream(PDFFileName, _
                           FileMode.Create, FileAccess.Write)
        PDFFile.Write(pdfBuffer, 0, pdfBuffer.Length)
        PDFFile.Close()

    Next

    'Zipping folder
    If System.IO.Directory.Exists(outPutDirectoryName) Then

        Dim fos As java.io.FileOutputStream
        Dim zos As java.util.zip.ZipOutputStream
        Dim di As System.IO.DirectoryInfo

        'create a zip file with same name in the same path
        If System.IO.File.Exists(zipFileName) Then
            System.IO.File.Delete(zipFileName)
        End If

        fos = New java.io.FileOutputStream(zipFileName)
        zos = New java.util.zip.ZipOutputStream(fos)
        di = New System.IO.DirectoryInfo(outPutDirectoryName)

        'procedure to zip a directory
        ZipFolder(fos, zos, di, outPutDirectoryName)
        zos.close()
        fos.close()
        zos.flush()
        fos.flush()

    End If

    DeleteOutputDirectory(outPutDirectoryName)
    Return zipFileName.Substring(zipFileName.LastIndexOf("\") + 1)

End Function

ZipFolder 过程将完成压缩

Private Sub ZipFolder(ByVal fileOutputStream As java.io.FileOutputStream _
                            , ByVal zipOutputStream As java.util.zip.ZipOutputStream _
                            , ByVal directoryInfo As System.IO.DirectoryInfo _
                            , ByVal SRootDir As String)

    Dim fileInputStream As java.io.FileInputStream
    Dim zipEntry As java.util.zip.ZipEntry

    Dim PDFReportInfos As System.IO.FileInfo() = directoryInfo.GetFiles
    Dim PDFReportInfo As System.IO.FileInfo

    For Each PDFReportInfo In PDFReportInfos
        zipEntry = New  java.util.zip.ZipEntry(_
           PDFReportInfo.FullName.Substring(SRootDir.LastIndexOf("\")))

        zipEntry.setMethod(zipEntry.DEFLATED)
        zipOutputStream.putNextEntry(zipEntry)

        fileInputStream = New java.io.FileInputStream(PDFReportInfo.FullName)

    Dim reader As New java.io.InputStreamReader(fileInputStream)
        Dim writer As New java.io.OutputStreamWriter(zipOutputStream)
        While reader.ready
            writer.write(reader.read)
        End While
        writer.flush()

        zipOutputStream.closeEntry()
        fileInputStream.close()
    Next

End Sub

结论

本文仅为您提供如何操作的概述,因为完整的代码超出了范围。

© . All rights reserved.