I read an excel file (.xlsm; password-protected) with a vb.net application. I use the following interfaces:
System.IO.filestream
Syncfusion.XlsIO (NuGet)
That works, but I want to open it in ReadOnly-Mode, so that any other people can use this file with MS Office (write, save, ...).
Code:
Imports Syncfusion.XlsIO
Private SyncEE As Syncfusion.XlsIO.ExcelEngine
Private SyncWB As Syncfusion.XlsIO.IWorkbook
Private SyncFS As System.IO.FileStream
Public Sub new
SyncEE = New ExcelEngine
SyncFS = New FileStream(PathFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
SyncEE.Excel.DefaultVersion = ExcelVersion.Excel2016
SyncWB = SyncEE.Excel.Workbooks.Open(SyncFS, ExcelParseOptions.Default, openReadOnly, password)
SyncWB.Unprotect(password)
SyncWB = SyncEE.Excel.Workbooks.Open(SyncFS, ExcelOpenType.Automatic)
' read....
'discard
SyncWB.Close()
SyncWB = Nothing
SyncEE.Dispose()
SyncEE = Nothing
SyncFS.Dispose()
SyncFS = Nothing
End Sub
I tried it step by step and found out that i block the file at row:
SyncFS = New FileStream(PathFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
and I release the file at the 'discard' rows.
Blocking means that no one can edit and save the excel-file manually in MS Excel while I read it.
Greetings from Syncfusion.
You are blocking the file on loading the file using FileStream, as mentioned by you and you are discarding the FileStream object only at the end of your entire program. You can discard the FileStream object immediately after loading it into a workbook object so that others can use the file with MS Office (write, save, …) while you are reading it. Hence, we have modified your code as below to achieve your requirement.
Code snippet:
Private Sub new
SyncEE = New ExcelEngine
SyncFS = New FileStream(PathFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
SyncEE.Excel.DefaultVersion = ExcelVersion.Excel2016
SyncWB = SyncEE.Excel.Workbooks.Open(SyncFS, ExcelParseOptions.Default, openReadOnly, password)
'Discard FileStream
SyncFS.Dispose()
SyncFS = Nothing
' read....
'discard
SyncWB.Close()
SyncWB = Nothing
SyncEE.Dispose()
SyncEE = Nothing
End Sub
Note: I work for Syncfusion.
Regards,
Shamini
Related
I want to import excel to devexpress grid.
When I runing in my PC, It work well.
But "Invalid file signature" error occurs in customer's PC.
So I get the customer's excel file(.xlsx) and open it my PC.
No error occurs in my PC. ...Why?
Here, my code to open excel file.
Dim stream As FileStream = File.Open(filePath, FileMode.Open, FileAccess.Read)
If UCase(strExt) = "XLS" Then
Dim excelReader As IExcelDataReader = ExcelReaderFactory.CreateBinaryReader(stream)
Dim excelDsConf As ExcelDataSetConfiguration = New ExcelDataSetConfiguration()
excelDsConf.ConfigureDataTable = Function() New ExcelDataTableConfiguration() With {
.UseHeaderRow = True
}
DtSet = excelReader.AsDataSet(excelDsConf)
DtSet.Tables(0).TableName = "ExcelData"
Else 'XLSX
Dim excelReader As IExcelDataReader = ExcelReaderFactory.CreateOpenXmlReader(stream)
Dim excelDsConf As ExcelDataSetConfiguration = New ExcelDataSetConfiguration()
excelDsConf.ConfigureDataTable = Function() New ExcelDataTableConfiguration() With {
.UseHeaderRow = True
}
DtSet = excelReader.AsDataSet(excelDsConf)
DtSet.Tables(0).TableName = "ExcelData"
End If
.Netframework is 4.0
Why "Invalid file signature" error occur in customer's PC?
What should I check on the customer's PC?
I'm working on a C# project that create, encrypt and send an excel file as an e-mail attachment.
I'm not looking to protect the excel, but encrypt it and set a password for opening it.
Is it even possible with the OpenXML SDK ?
I tried that, but I don't think this is for encrypting :
string hexConvertedPassword = HexPasswordConversion("Azerty123");
WorkbookProtection WorkbookProt = new WorkbookProtection()
{
WorkbookPassword = hexConvertedPassword,
RevisionsPassword = hexConvertedPassword,
LockRevision = true,
LockStructure = true,
LockWindows = true,
};
Workbook workbook = new Workbook();
workbook.Append(WorkbookProt);
I have already search in the documentation, but may have missed it.
I know some library can do it like devexpress, EasyXLS, Spire.Xls, etc, but those are very expensive.
You can try to encrypt the content of DOCUMENT via reading cell by cell and generate a new .xlsx file.
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
string text;
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
// send to ecryption function.
text = c.CellValue.Text;
Console.Write(text + " ");
}
}
For more details visit: https://learn.microsoft.com/en-us/office/open-xml/how-to-parse-and-read-a-large-spreadsheet
In the end I used FreeSpire.XLS to load my existing Excel file and add the encryption over it. Hopefully there is no limitation to load and save file with the free version.
I use the following code to open an excel-file:
Private EPXlApp As OfficeOpenXml.ExcelPackage
Private EPXlFile As FileInfo
Private EPXlSheet As ExcelWorksheet
Private EPXlWorkbook As ExcelWorkbook
Public Sub New(newFilePath As String, Optional password As String = "")
PathFile = newFilePath
OfficeOpenXml.ExcelPackage.LicenseContext = LicenseContext.NonCommercial
EPXlFile = New FileInfo(PathFile)
EPXlApp = New OfficeOpenXml.ExcelPackage(EPXlFile, password) ' ---> here the error occurs
EPXlWorkbook = EPXlApp.Workbook
EPXlSheet = EPXlApp.Workbook.Worksheets(1)
End sub
This works. But if one person block the file, i can't open it again. I don't understand the error message
System.IO.InvalidDataException: "File S:\Team\file.xlsm is not an encrypted package"
because thats the rigt password, it has already worked if no one blocked the excel file.
Thank you very much in advance!
I am developing a website on VisualStudio using VB. In one section of my site I make a DataBase Query, store the result in a DataTable and display it. I give the user the option of dowloading the information, what I would like to do is to download an XLS file to the client's side with the information in the datatable without creating the xls on the server side.
I currently have the following code section to send the file to the user
Dim fileToDownload = Server.MapPath("~/docs/QuejometroVF.pdf")
Response.ContentType = "application/octet-stream"
Dim cd = New ContentDisposition()
cd.Inline = False
cd.FileName = Path.GetFileName(fileToDownload)
Response.AppendHeader("Content-Disposition", cd.ToString())
Dim fileData = System.IO.File.ReadAllBytes(fileToDownload)
Response.OutputStream.Write(fileData, 0, fileData.Length)
But it requires a path to a local file in order to send it.
First I would like to know how to create a xls file from the datatable (only in memory) and then send that object as a file to the client's computer. If it is not possible, Could you tell me how to write the xls file in my server so I can then send it using the code above? I have not really figured out how to do it yet.
I was thinking on doint it that way because I don't want to keep files in the server when I already have that information on the database and I don't pretend on keeping that file stored.
Thank you
I export data to xls file using the following code, my backend is an Oracle database and that's where I get the data:
Dim MyConnection As OracleConnection = OpenConnection(Session("USERNAME"), Session("PASSWORD"))
Dim MyDataSet As New DataSet
MyDataSet = GetExportData(MyConnection, Session("UserDataKey"), Session("CompoundKey"), Session("LastOfCompoundKey"))
'I rename the dataset's table columns to what I want in the xls file
MyDataSet.Tables!data.Columns(0).ColumnName = "IDNumber"
MyDataSet.Tables!data.Columns(1).ColumnName = "FirstName"
MyDataSet.Tables!data.Columns(2).ColumnName = "LastName"
MyDataSet.Tables!data.Columns(3).ColumnName = "Address"
MyDataSet.Tables!data.Columns(4).ColumnName = "City"
MyDataSet.Tables!data.Columns(5).ColumnName = "State"
MyDataSet.Tables!data.Columns(6).ColumnName = "ZipCode"
MyDataSet.Tables!data.Columns(7).ColumnName = "Phone_Area"
MyDataSet.Tables!data.Columns(8).ColumnName = "Phone_Prefix"
MyDataSet.Tables!data.Columns(9).ColumnName = "Phone_Suffix"
MyDataSet.Tables!data.Columns(10).ColumnName = "Email"
MyDataSet.Tables!data.Columns(11).ColumnName = "BirthDay"
Response.ClearContent()
'I create the filename I want the data to be saved to and set up the response
Response.AddHeader("content-disposition", "attachment; filename=" & Replace(Session("Key0"), " ", "-") & "-" & Session("Key1") & "-" & Replace(Replace(Trim(Session("Key2")), ".", ""), " ", "-") & ".xls")
Response.ContentType = "application/excel"
Response.Charset = ""
EnableViewState = False
Dim tw As New System.IO.StringWriter
Dim hw As New System.Web.UI.HtmlTextWriter(tw)
'Create and bind table to a datagrid
Dim dgTableForExport As New DataGrid
If MyDataSet.Tables.Count > 0 Then
If MyDataSet.Tables(0).Rows.Count > 0 Then
dgTableForExport.DataSource = MyDataSet.Tables(0) ' .DefaultView
dgTableForExport.DataBind()
'Finish building response
Dim strStyle As String = "<style>.text { mso-number-format:\#; } </style>"
For intTemp As Integer = 0 To MyDataSet.Tables(0).Rows.Count - 1
For intTemp2 As Integer = 0 To MyDataSet.Tables(0).Columns.Count - 1
dgTableForExport.Items(intTemp).Cells(intTemp2).Attributes.Add("class", "text")
Next
Next
End If
End If
dgTableForExport.RenderControl(hw)
Response.Write(style)
' Write the HTML back to the browser.
Response.Write(tw.ToString())
Response.End()
'Close, clear and dispose
MyConnection.Close()
MyConnection.Dispose()
MyConnection = Nothing
I copied and pasted this from one of my projects, it's untested and may contain error but should get you started.
You can use a MemoryStream or to write the file to Response stream using Response.Write method.
Creating an excel file from a data table is fairly easy as you can just create a GridView and bind the table to it.
Here is a code snippet that does what you need.
Public Sub DownloadExcel(outputTable as System.Data.DataTable)
Dim gv As New GridView
Dim tw As New StringWriter
Dim hw As New HtmlTextWriter(tw)
Dim sheetName As String = "OutputFilenameHere"
gv.DataSource = outputTable
gv.DataBind()
gv.RenderControl(hw)
Response.AddHeader("content-disposition", "attachment; filename=" & sheetName & ".xls")
Response.ContentType = "application/octet-stream"
Response.Charset = ""
EnableViewState = False
Response.Write(tw.ToString)
Response.End()
End Sub
There are a few issues with this method:
This doesn't output a native excel file. Instead, it outputs the HTML for a GridView that Excel will detect and notify the user that the content doesn't match the extension. However, it WILL display in Excel correctly if the user selects 'Yes' from the dialog box.
Earlier versions of Firefox and Chrome didn't like this method and instead download the file with a .html extension. I just tested it in both browsers and it worked with the most up to date versions.
Ideally, you should probably use Excel on your webserver to create native spreadsheets, but this will work if you (like me) don't have the means to do so.
when i tried to save a read- only ppt/pptx to a pdf i got a msg as shown below
below is my code:
Microsoft.Office.Interop.PowerPoint.Application pptApplication = new Microsoft.Office.Interop.PowerPoint.Application();
pptApplication.DisplayAlerts = PpAlertLevel.ppAlertsNone;
Microsoft.Office.Interop.PowerPoint.Presentation pptPresentation = pptApplication.Presentations.Open("E:\\Share Box\\data.pptx", MsoTriState.msoTriStateMixed,
MsoTriState.msoFalse, MsoTriState.msoFalse);
string temp = pptPresentation.ReadOnly.ToString();
pptPresentation.SaveAs("E:\\Share Box\\"+DateTime.Now.Second.ToString(), PpSaveAsFileType.ppSaveAsPDF, MsoTriState.msoTrue);
pptPresentation.Close();
Marshal.FinalReleaseComObject(pptPresentation);
pptPresentation = null;
pptApplication.Quit();
Marshal.FinalReleaseComObject(pptApplication);
pptApplication = null;
GC.Collect();
anyone could help me to fix this.
I tried this code and it's working fine.For this I used interop assemblies downloaded from
http://www.microsoft.com/en-in/download/details.aspx?id=3508
Please see this also
http://support.microsoft.com/kb/873433