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






3.69/5 (6投票s)
解释如何在 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
结论
本文仅为您提供如何操作的概述,因为完整的代码超出了范围。