How to show window prompt for downloading excel file? - asp.net

I have written code for exporting data to xlsx file. But i dont understand how to show window prompt for downloading that xlsx file at client end.
Here's my code:
Private Sub DataTableToExcel(ByVal tbl As DataTable)
Dim Excel As Object = CreateObject("Excel.Application")
Dim strFilename As String
Dim intCol, intRow As Integer
Dim strPath As String = "C:\"
If Excel Is Nothing Then
MsgBox("It appears that Excel is not installed on this machine. This operation requires MS Excel to be installed on this machine.", MsgBoxStyle.Critical)
Return
End If
Try
With Excel
.SheetsInNewWorkbook = 1
.Workbooks.Add()
.Worksheets(1).Select()
.cells(1, 1).value = "Complaint Detail Report" 'Heading of the excel file
.cells(1, 1).EntireRow.Font.Bold = True
Dim intI As Integer = 1
For intCol = 0 To tbl.Columns.Count - 1
.cells(2, intI).value = tbl.Columns(intCol).ColumnName
.cells(2, intI).EntireRow.Font.Bold = True
intI += 1
Next
intI = 3
Dim intK As Integer = 1
For intCol = 0 To tbl.Columns.Count - 1
intI = 3
For intRow = 0 To tbl.Rows.Count - 1
.Cells(intI, intK).Value = tbl.Rows(intRow).ItemArray(intCol)
intI += 1
Next
intK += 1
Next
If Mid$(strPath, strPath.Length, 1) <> "\" Then
strPath = strPath & "\"
End If
strFilename = strPath & "ComplaintDetail.xlsx"
.ActiveCell.Worksheet.SaveAs(strFilename)
End With
System.Runtime.InteropServices.Marshal.ReleaseComObject(Excel)
Excel = Nothing
MsgBox("Data's are exported to Excel Succesfully: Location: '" & strFilename & "'", MsgBoxStyle.Information)
' Response.AddHeader("content-disposition", "attachment;filename=ComplaintDetail.xlsx")
'Response.ContentType = "application/vnd.excel"
Catch ex As Exception
MsgBox(ex.Message)
End Try
Dim pro() As Process = System.Diagnostics.Process.GetProcessesByName("EXCEL")
For Each i As Process In pro
i.Kill()
Next
End Sub
Here I am saving .XLSX file directly to "C Drive".
Why I choose C Drive? : Because 99% of people have C: in there pc.
But I got some scenario where user don't allow access of their C drive or they don't give permission to write anything inside c drive.
That's why I am trying to add this window prompt where user will decide where to save that file. But i got some issue in above code.
Can you please help me to add window prompt in above code?

Save in the App_Data directory. You can find the absolute path with Server.MapPath("~/App_Data") This path is writeable by the application
Use Response.TransmitFile to make the file to be downloaded.

Try using something like a save file dialog (this can be added via the ui designer).
Then use:
If dialog.Show() = Windows.Forms.DialogResult.OK Then
strPath = dialog.FileName
End If

Related

How to fix 0x800A03EC error when exporting a Datatable to Excel

I am trying to export a datatable to Excel and am getting the following Exception when running wb.SaveAs(path):
Exception from HRESULT: 0x800A03EC
Initially I was getting this error when setting the worksheet range. I fixed this by making it non-zero indexed. However, the datatable array is still zero indexed.
Unfortunately, no additional details for the error are given.
Code:
Dim app As New Excel.Application
Dim wb As Excel.Workbook = app.Workbooks.Add()
Dim ws As Excel.Worksheet
Dim strFN As String = "MyFileName.xlsx"
Dim dt As New DataTable
Using da As New DataAdapter(dif)
da.SetSelectCommand(SQL)
da.Fill(dt)
End Using
ws = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
DataTableToExcel(dt, ws, "TableName")
wb.SaveAs(path)
wb.Close()
Private Sub DataTableToExcel(dt As DataTable, ws As Excel.Worksheet, TabName As String)
Dim arr(dt.Rows.Count, dt.Columns.Count) As Object
Dim r As Int32, c As Int32
For r = 0 To dt.Rows.Count - 1
For c = 0 To dt.Columns.Count - 1
arr(r, c) = dt.Rows(r).Item(c)
Next
Next
ws.Name = TabName
c = 0
For Each column As DataColumn In dt.Columns
If column.ColumnName.Length > 4 Then
If column.ColumnName.Substring(column.ColumnName.Length - 4, 4) = "_ID" Then
ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ").Substring(0, column.ColumnName.Length - 4)
Else
ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ")
End If
Else
ws.Cells(1, c + 1) = column.ColumnName.Replace("_", " ")
End If
c += 1
Next
ws.Range(ws.Cells(2, 1), ws.Cells(dt.Rows.Count, dt.Columns.Count))(1).Value = arr
End Sub
UPDATE:
I've managed to stop the error from occuring by changing SaveAs() to SaveCopyAs().
The file now exports but when I open it, all there is are column names and only the first value of the first column/row.
Launching Excel just to export data to an Excel file is overkill. For web sites it's completely impractical for several reasons:
You need a license for every user of the site. That's a lot of money.
It's way too easy to leave Excel open, slowly eating up the server's RAM and CPU.
It's just too slow
xlsx is a ZIP package containing well-defined XML files, so one can create them directly, use the Open XML SDK or one of the many open source libraries that make this a lot easier, like Epplus, NPOI or ClosedXML.
For example, Epplus allows filling an Excel sheet from a DataTable, IEnumerable or IDbDataReader with a single call:
Dim dt As DataTable = ...
Dim fi New FileInfo(SomePath)
Using p As New ExcelPackage(fi)
Dim ws = p.Workbook.Worksheets.Add(sheetName)
ws.Cells("A1").LoadFromDataTable(dt, PrintHeaders:=True)
p.Save()
End Using
You can also use LoadFromDataReader and avoid loading all the data into memory:
Using cmd As New SqlCommand(sql,connection)
connection.Open()
Using reader As SqlDataReader = cmd.ExecuteReader()
Dim fi New FileInfo(SomePath)
Using p As New ExcelPackage(fi)
Dim ws = p.Workbook.Worksheets.Add(sheetName)
ws.Cells("A1").LoadFromDataReader(reader, PrintHeaders:=True)
p.Save()
End Using
End Using
End Using

VB.NET FTP Picture Upload Error [duplicate]

This question already has answers here:
Zip file is getting corrupted after downloading from server in C#
(3 answers)
Closed 4 years ago.
I am trying to allow authenticated users to upload pictures to the server through FTP. The code works for the most part. The part that doesn't is that there is an issue in uploading the file. I have tried to upload a few different pictures and all of them are larger on the server and therefore, not properly constructed.
One picture I tried is 4.56MB on my computer and 8.24MB on the server. When I load the picture in Photo, it states "We can't open this file." The page location is at http://troop7bhac.com/pages/slideshowedit.aspx. The following is the VB.NET code behind the upload:
Sub uploadFile_Click(sender As Object, e As EventArgs)
lblUploadErrors.InnerHtml = ""
If (lstSlideshowChoose.SelectedValue = "") Then
lblUploadErrors.InnerHtml = "<p>A slideshow must be selected.</p>"
Else
If (FileUpload1.HasFile) Then
Dim nameList() As String
Dim successList() As String
Dim i As Integer = 0
For Each file As HttpPostedFile In FileUpload1.PostedFiles
Dim fileBytes() As Byte = Nothing
Dim fileName As String = Path.GetFileName(file.FileName)
Dim photoRE As New Regex("^[A-z0-9 _]{1,}\.jpg|JPG|jpeg|JPEG|png|PNG+$")
Dim photoSuccess As Boolean = photoRE.Match(fileName).Success
ReDim Preserve nameList(i)
ReDim Preserve successList(i)
If (photoSuccess = True) Then
Using fileStream As New StreamReader(file.InputStream)
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd())
fileStream.Close()
End Using
Try
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(ftpPath & lstSlideshowChoose.SelectedValue & "/" & fileName), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.Credentials = New NetworkCredential(ftpUser, ftpPass)
Using uploadStream As Stream = request.GetRequestStream()
uploadStream.Write(fileBytes, 0, fileBytes.Length)
uploadStream.Close()
End Using
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
response.Close()
successList(i) = "Success "
Catch ex As Exception
successList(i) = "Failed "
End Try
Else
successList(i) = "Failed "
End If
nameList(i) = fileName
i += 1
Next
For x As Integer = 0 To nameList.Count - 1
lblUploadErrors.InnerHtml += "<p>" & successList(x) & nameList(x) & "</p>"
Next
Else
lblUploadErrors.InnerHtml = "<p>You have not selected a picture to upload.</p>"
End If
End If
End Sub
The files are obtained through an ASP.NET FileUpload control. The control has been set to allow multiple files at once.
Any help to figure out why the pictures are not uploading properly would be greatly appreciated.
EDIT: I tried Martin Prikryl's possible duplicate solution. Had to change it from C# to VB.NET. It failed. I tried David Sdot's solution and it also failed. Both solutions returned the same errors.
If the page was ran on my local machine, it returned "C:\Program Files (x86)\IIS Express\PictureName.JPG." If the page was ran on the server, it returned "C:\Windows\SysWOW64\inetsrv\PictureName.JPG." Both errors are of the System.IO.FileNotFoundException class.
Your Problem is here:
Using fileStream As New StreamReader(file.InputStream)
fileBytes = Encoding.UTF8.GetBytes(fileStream.ReadToEnd())
fileStream.Close()
Using
Your image is read as text. From this text you get the bytes UTF8 byte values, thats why your image is nearly twice the size when uplaoded. You need the bytes from the image, without converting them to something else.
fileBytes = File.ReadAllBytes(file.FileName)

File filtering (ASP.Net, VB.Net)

I am making a filtering on files selected by user. Here is my coding that I currently use for button upload click event.
Dim validFileTypes As String() = {"jpg", "JPG", "jpeg", "JPEG", "png", "PNG"}
Dim ext As String = Path.GetExtension(fileUpload.PostedFile.FileName)
Dim isValidFile As Boolean = False
If fileUpload.HasFile Then
For i As Integer = 0 To validFileTypes.Length - 1
If ext = "." & validFileTypes(i) Then 'if selected url got extension like listed above
isValidFile = True 'file is valid
Dim hfc As HttpFileCollection = Request.Files
For j As Integer = 0 To hfc.Count - 1
Dim hpf As HttpPostedFile = hfc(j)
If hpf.ContentLength > 0 Then
hpf.SaveAs(Server.MapPath("source") & "\" & Path.GetFileName(hpf.FileName))
End If
Next
Else
Alert("Failed to upload! Please select file with valid extension.")
End If
Next
Else
Alert("Please select image!")
End If
So if user select file with wrong extension, file will not be uploaded into temporary file. Since the validFileTypes consist of 6 types so the Alert("Failed to upload! Please select file with valid extension.") will appear 6 times even though the file selected is only 1. I tried to fix it but need some guidance from you guys. Thank you.
I have made some improvements on your code and fixed some of the downsides for you.
Dim validExtensions As String() = {"jpg", "JPG", "jpeg", "JPEG", "png", "PNG"}
' Check if request has no file
If Request.Files.Count = 0 Then
Alert("Please select image!")
Else
'Otherwise get files from request
Dim files As HttpFileCollection = Request.Files
'Loop through file names
For Each fileName as String In files.AllKeys
'Get file from posted files
Dim file As HttpPostedFile = files(fileName)
'Check content length of file
If file.ContentLength > 0 Then
'Get file extension of file
Dim extension As String = Path.GetExtension(file.FileName)
'Check if file extension is valid
If validFileTypes.Contains(extension) Then
'Save file
file.SaveAs(Server.MapPath("source") & "\" & Path.GetFileName(file.FileName))
Else
Alert("Failed to upload! Please select file with valid extension.")
Exit For 'Break loop
End If
End If
Next
End If

Export Crystal Report to PDF in a Loop only works with first

i'm trying to generate a report and export it to pdf in a loop, the report will receive a new parameter in each loop and prompt the client to download a PDF, in other words, the client may need to download 2 or 3 (or more) PDFs at the same time, the problem is that the prompt to accept the download only appears for the first pdf, dont know why. I can export to disk (server side) without any problems.
Code:
Sub PrintReport(ByVal Cod As Integer)
Dim CTableLogInfo As TableLogOnInfo
Dim ConnInfo As CrystalDecisions.Shared.ConnectionInfo = New ConnectionInfo()
ConnInfo.Type = ConnectionInfoType.SQL
ConnInfo.ServerName = ConfigurationManager.AppSettings("SQLSERVERNAME")
ConnInfo.DatabaseName = ConfigurationManager.AppSettings("SQLDBNAME")
ConnInfo.UserID = ConfigurationManager.AppSettings("SQLSERVERUSER")
ConnInfo.Password = ConfigurationManager.AppSettings("SQLSERVERPASSWORD")
ConnInfo.AllowCustomConnection = False
ConnInfo.IntegratedSecurity = False
For Each CTable As Table In CrystalReportSource1.ReportDocument.Database.Tables
CTable.LogOnInfo.ConnectionInfo = ConnInfo
CTableLogInfo = CTable.LogOnInfo
CTableLogInfo.ReportName = CrystalReportSource1.ReportDocument.Name
CTableLogInfo.TableName = CTable.Name
CTable.ApplyLogOnInfo(CTableLogInfo)
Next
Dim pField As ParameterField = CrystalReportSource1.ReportDocument.ParameterFields(0)
Dim val1 As ParameterDiscreteValue = New ParameterDiscreteValue
val1.Value = Cod
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
Dim PDFName As String = "PDF Nº " & Cod
CrystalReportSource1.ReportDocument.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Page.Response, True, PDFName)
End Sub
EDIT:
Tried to zip the reports with DotNetZip but i get an broken zip.
Can you tell me whats wrong? (Solved: code bellow is corrected now)
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/zip"
Response.AppendHeader("content-disposition", "attachment; filename=AllPDFs.zip")
Using zipFile As New ZipFile()
For i = 0 To Cod.Length - 1
If Cod(i) > 0 Then
val1.Value = Cod(i)
pField.CurrentValues.Clear()
pField.CurrentValues.Add(val1)
val2.Value = Cod(i)
pField2.CurrentValues.Clear()
pField2.CurrentValues.Add(val2)
Dim PDFNameAs String = "PDF Nº " & Cod(i) & ".pdf"
Dim s As New System.IO.MemoryStream
s =CrystalReportSource1.ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat)
zipFile.AddEntry(PDFName, s)
End If
Next
zipFile.Save(Response.OutputStream)
End Using
Response.Clear()
Probably the response ends after the first one, therefore there's no response to write to for the 2nd and 3rd attempts.
Instead, you can have the client download the reports via AJAX Request (move your report generation into an .ashx generic handler), or have the user click the button 3 times to initiate new requests.
Or zip the PDF's up until a single file and allow the client to download that.

extract attachments from DB to separate folders for each document

Have an assignment to do - it's to extract data from Lotus Notes DB including documents and their attachments. The purpose of this is to put it and store on the Sharepoint as a library.
So far I have managed to create a view and export the data for it to structure in Excel.
Also, I have looked up some Agents examples for extracting the attachments. With implementation of the below script, I managed to export the attachments:
Dim sDir As String
Dim s As NotesSession
Dim w As NotesUIWorkspace
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
Sub Initialize
Set s = New NotesSession
Set w = New NotesUIWorkspace
Set db = s.CurrentDatabase
Set dc = db.UnprocessedDocuments
Set doc = dc.GetFirstDocument
Dim rtItem As NotesRichTextItem
Dim RTNames List As String
Dim DOCNames List As String
Dim itemCount As Integer
Dim sDefaultFolder As String
Dim x As Integer
Dim vtDir As Variant
Dim iCount As Integer
Dim j As Integer
Dim lngExportedCount As Long
Dim attachmentObject As Variant
x = MsgBox("This action will extract all attachments From the " & CStr(dc.Count) & _
" document(s) you have selected, And place them into the folder of your choice." & _
Chr(10) & Chr(10) & "Would you like To continue?", 32 + 4, "Export Attachments")
If x <> 6 Then Exit Sub
sDefaultFolder = s.GetEnvironmentString("LPP_ExportAttachments_DefaultFolder")
If sDefaultFolder = "" Then sDefaultFolder = "F:"
vtDir = w.SaveFileDialog( False, "Export attachments To which folder?", "All files|*.*", sDefaultFolder, "Choose Folder and Click Save")
If IsEmpty(vtDir) Then Exit Sub
sDir = StrLeftBack(vtDir(0), "\")
Call s.SetEnvironmentVar("LPP_ExportAttachments_DefaultFolder", sDir)
While Not (doc Is Nothing)
iCount = 0
itemCount = 0
lngExportedCount = 0
Erase RTNames
Erase DocNames
'Scan all items in document
ForAll i In doc.Items
If i.Type = RICHTEXT Then
Set rtItem = doc.GetfirstItem(i.Name)
If Not IsEmpty(rtItem.EmbeddedObjects) Then
RTNames(itemCount) = CStr(i.Name)
itemCount = itemCount +1
End If
End If
End ForAll
For j = 0 To itemCount-1
Set rtItem = Nothing
Set rtItem = doc.GetfirstItem(RTNames(j))
ForAll Obj In rtItem.EmbeddedObjects
If ( Obj.Type = EMBED_ATTACHMENT ) Then
Call ExportAttachment(Obj)
Call doc.Save( False, True )
'creates conflict doc if conflict exists
End If
End ForAll
Next
'Scan all items in document
ForAll i In doc.Items
If i.Type = ATTACHMENT Then
DOCNames(lngExportedCount) = i.Values(0)
lngExportedCount = lngExportedCount + 1
End If
End ForAll
For j% = 0 To lngExportedCount-1
Set attachmentObject = Nothing
Set attachmentObject = doc.GetAttachment(DOCNames(j%))
Call ExportAttachment(attachmentObject)
Call doc.Save( False, True )
'creates conflict doc if conflict exists
Next
Set doc = dc.GetNextDocument(doc)
Wend
MsgBox "Export Complete.", 16, "Finished"
End Sub
Sub ExportAttachment(o As Variant)
Dim sAttachmentName As String
Dim sNum As String
Dim sTemp As String
sAttachmentName = sDir & "\" & o.Source
While Not (Dir$(sAttachmentName, 0) = "")
sNum = Right(StrLeftBack(sAttachmentName, "."), 2)
If IsNumeric(sNum) Then
sTemp = StrLeftBack(sAttachmentName, ".")
sTemp = Left(sTemp, Len(sTemp) - 2)
sAttachmentName = sTemp & Format$(CInt(sNum) + 1, "##00") & _
"." & StrRightBack(sAttachmentName, ".")
Else
sAttachmentName = StrLeftBack(sAttachmentName, ".") & _
"01." & StrRightBack(sAttachmentName, ".")
End If
Wend
Print "Exporting " & sAttachmentName
'Save the file
Call o.ExtractFile( sAttachmentName )
End Sub
So the issue I do have right now is that these attachments are being saved to the same folder, which means that I would manually have to put them into right folders of library (several thousands). Could anyone help on how should I change the above code to have the attachments saved to separate folder for each document from DB?
Also for some reason that I cant find out below line is causing error pop up with "Object Variable not set":
sAttachmentName = sDir & "\" & o.Source
Would anyone know why it causes failure and stops the whole process?
You need to use the MkDir statement to create directory and extract attachments in the folder. Probably write something like:
MkDir sDir
You need to write code that create a new directory for each document (make sure you check if the directory exists, and preferably you make sure each directory has a unique name).
I wrote a tool like that, that exports all the fields of a document into XML, as well as attachments and embedded images. It can be set to separate each document into it's own directory.
You can read more about it ate the link below, perhaps you can get some ideas from the description. I use the UniversalID of teh document to get a unique folder name.
http://www.texasswede.com/websites/texasswede.nsf/Page/Notes%20XML%20Exporter

Resources