Upload Excel file and extract data - asp.net mvc 3 - c#

I am wondering how do I extract data out of a 2007 excel file? I am using asp.net mvc 3. My plan is to have a upload section that you choose a file and hit upload. I have no clue after that what kind of format it will be or what I need to do to extract the values out.
Thanks

Once you have the spreadsheet uploaded and you save it to a file on the web server it is quite easy to use LINQ to select the rows from the spreadsheet. Check this out for more info.
http://code.google.com/p/linqtoexcel/

The easiest way to read excel spread sheets IMO is to use a DataAdapter and an OleDB connection as shown in this code project sample. The good thing about this is it does not have any dependencies on COM or the MS office libraries.

For reading Excel files, I learned to love Koogra. It's an open source library that reads both xls and xlsx files, and is very easy to use.
http://sourceforge.net/projects/koogra/

I've used NPOI and it's quite simple to use:
Using Xlfile As FileStream = New FileStream(FileName, FileMode.Open, FileAccess.Read)
Using XLBook As HSSFWorkbook = New HSSFWorkbook(Xlfile)
Using XLSheet As NPOI.SS.UserModel.Sheet = XLBook.GetSheetAt(0)
Dim CurrentRow As NPOI.HSSF.UserModel.HSSFRow
Dim CurrentCell As NPOI.SS.UserModel.Cell
Dim RowEnum As IEnumerator = XLSheet.GetRowEnumerator()
While RowEnum.MoveNext
If (RowEnum.Current IsNot Nothing) Then
CurrentRow = TryCast(RowEnum.Current, NPOI.HSSF.UserModel.HSSFRow)
Select Case CurrentCell.CellType
Case NPOI.SS.UserModel.CellType.STRING
' CurrentCell.StringCellValue
Case NPOI.SS.UserModel.CellType.NUMERIC
' CurrentCell.NumericCellValue.ToString()
End Select
End While
End Using
End Using
Xlfile.Close()
End Using

Related

Open workbook in Interop.Excel from byte array

I want to open Excel from byte[] because my file is encrypted and I want to open after decrypt but without write in a file.
The office has "restricted access" and I want to open my file with this protection but without saving the decrypted content in a file.
myApp.Workbooks.Open only supports a path.
Is it possible?
As an alternative to OpenXml there's also ExcelDataReader which from my experience is a lot faster in processing data compared to Interop.Excel(around 3 times+).
It can also open encrypted Excel files directly(stackoverflow)
The github page for ExcelDataReader has some great examples on how to use it. The only thing you'd have to do is:
This:
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
Becomes this:
using (var stream = new MemoryStream(yourByte[])
And if you just want to open the password protected excel file you'd do this:
var conf = new ExcelReaderConfiguration { Password = "yourPassword" }; //Add this
excelReader = ExcelReaderFactory.CreateReader(stream, conf); //change the excel Reader to this
Make sure to check the Github page for more info!
It is not possible because the interop is actually an interface for programs to run and operate existing excel on the computer.
I think you need to use openxml created by Microsoft to work with excel word and PowerPoint.
DocumentFormat.OpenXml
Then you can use:
ExcelPackage excelPackage = new ExcelPackage(stream)
or
var pck = new OfficeOpenXml.ExcelPackage();
pck.Load(File.OpenRead(path));
pck.Load(Stream) can use any stream as input not only from a file.
It depends on your needs.

Write an Excel file with C# [duplicate]

Is there any easy to implement library that can be used to read excel files and may be create them later on?
is this my best bet?
http://support.microsoft.com/kb/302084
Try this: http://epplus.codeplex.com
EPPlus is a .net library that reads and writes Excel 2007/2010 files
using the Open Office Xml format (xlsx).
If you are willing to commit yourself to a later version of Excel (2007+) you can also take a look at the OpenXML SDK. It's free, doesn't tie you to having MS Office installed on the machine it will be running on and there are quite a few resources available on how to use it online (including blogs from the OpenXML team).
There is excel package plus:
http://epplus.codeplex.com/
Only works on xlsx though, but Office 2003 is cycling out anyway.
You can use ExcelLibrary ,Although it works for .xls only which is 2003 format
The aim of this project is provide a native .NET solution to create, read and modify Excel files without using COM interop or OLEDB connection.
I had a chance of using EPPLUS ,it was wonderful :) ,It works for new excel format .xlsx which is used in 2007/2010
EPPlus is a .net library , you can read and write to excel files ,create charts ,pictures ,shapes... and Much more
Also take a look at this SO post
I've used oledb, interop and just started using Epplus. So far epplus is proving to be simplest.
http://epplus.codeplex.com/
However, I just posted a problem I have with epplus, but I posted some code you could use as reference.
c# epplus error Removed Part: Drawing shape
I like to use ExcelDataReader for reading and the aforementioned EPPlus for writing. Here's an example.
Here's an example of reading with it:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
// Reading from a binary Excel file ('97-2003 format; *.xls)
// IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
// Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
// Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
var cdm = new ValueSetRepository();
for (int i = 0; i < result.Tables.Count; i++)
{
// CHECK if tableNames filtering is specified
if (tableNames != null)
{
// CHECK if a table matches the specified tablenames
var tablename = result.Tables[i].TableName;
if (!tableNames.Contains(tablename))
{
continue;
}
}
var lookup = new ValueSetLookup();
lookup.CmsId = result.Tables[i].Rows[2][0].ToString();
lookup.NqfNumber = result.Tables[i].Rows[2][1].ToString();
lookup.Data = new List<ValueSetAttribute>();
int row_no = 2;
while (row_no < result.Tables[i].Rows.Count) // i is the index of table
// (sheet name) which you want to convert to csv
{
var currRow = result.Tables[i].Rows[row_no];
var valueSetAttribute = new ValueSetAttribute()
{
Id = currRow[0].ToString(),
Number = currRow[1].ToString(),
tName = currRow[2].ToString(),
Code = currRow[7].ToString(),
Description = currRow[8].ToString(),
};
lookup.Data.Add(valueSetAttribute);
row_no++;
}
cdm.AddRecord(lookup);
A company I used to work for did a lot of research on this and decided a product by SoftArtisans was their best bet:
OfficeWriter
I always found it strange how weak the support for Excel reading and writing was. I'm pretty sure that if you use Microsoft's libraries you have to have Excel installed anyway which is an extra expense just like OfficeWriter.
You could either go for VBA or use the free library from FileHelpers. If you are planning to buy some commerical solutions, I would recommend ASPOSE
According to this website you need to include a reference to the Microsoft Excel 12.0 Object library. From there, you need to do a few things to open up the file. There's a code sample on the website.
PS - Sorry it's not too detailed but I couldn't find the Microsoft Office developer reference with more details.
I used ExcelLibrary with very great results! (until now it support Excel 2003 or lower versions).
http://code.google.com/p/excellibrary/
Yes, multiple open-source libraries exist to help read and/or write Excel spreadsheets using C#.
Here is a shortlist of C# libraries:
Microsoft.Office.Interop.Excel
ExcelDataReader
NPOI
ExcelMapper - NPOI extension
EPPlus
An up-to-date curated list is maintained here.
Example: Reading Excel File using ExcelMapper
a. Install using NuGet, by running below command in NuGet Packet Manager:
Install-Package ExcelMapper
b. Sample C# Code for ExcelMapper
public void ReadExcelUsingExcelMapperExtension()
{
string filePath = #"C:\Temp\ListOfPeople.xlsx";
var people = new ExcelMapper(filePath).Fetch<Person>().ToList();
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
Disclaimer: I like the conciseness of ExcelMapper, therefore included sample code for this package. To do the same using other libraries, requires a lot more code.

Open excel with EPPlus without saving to file

Rright now I'm opening excel using
System.Diagnostics.Process.Start(fileInfo);
to open my package after saving it to a file.
Is it possible to open excel without having to save the file to a location? I would like the user to decide whether or not to save the file.
If you're generating the file yourself using EPPlus (or any other libraries that generate the file directly), you'll need to save it before you can open it in Excel. I'd recommend just saving it in the temp directory, then showing it to the user and letting them choose what to do with it.
If you generate the file using Office Automation, you can display it to the user before saving it.
I think this answer will help new developer.
I think best option for viewing Excel without saving is Microsoft.Office.Interop.Excel
Open Nuget Package Console Install-Package Microsoft.Office.Interop.Excel
create Excel file here is the official documentation Excel
at the end of filling Excel file just type app.Visible = true; app is the object name
I know this is late, but I had the same issue.
I used to use Microsoft.Office.Interop.Excel to export data to an xlsx file without saving it. It would present itself nicely as Book1.xlsx to the end-user who could them save it or close it without saving as required.
I have also moved to EPPlus to improve the speed of my exports and therefore, as you have experienced, cannot present the open file to the end-user without it first being saved.
The approach I have taken, using the SaveFileDialog component is to prompt the user for a name before the EPPlus file is created. This at least allows the end-user to identify where the file should be saved, rather than using a 'hard-coded' directory.
Private Sub btnExportXlsxEPPlus_Click(sender As Object, e As EventArgs) Handles btnExportXlsxEPPlus.Click
Try
Dim filInf As FileInfo = New FileInfo(GetFileToSave())
Using excelPackage As ExcelPackage = New ExcelPackage
excelPackage.Workbook.Properties.Author = "enLIGHTen"
excelPackage.Workbook.Properties.Title = "enLIGHTen Report"
excelPackage.Workbook.Properties.Subject = "enLIGHTen export data"
excelPackage.Workbook.Properties.Created = Date.Now
Dim worksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets.Add("Sheet 1")
worksheet.Cells("A1").Value = "My EPPlus spreadsheet!"
worksheet.Cells(1, 2).Value = "This is cell B1!"
excelPackage.SaveAs(filInf)
End Using
Using excelPackage As ExcelPackage = New ExcelPackage(filInf)
Dim firstWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets(1)
Dim namedWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets("SomeWorksheet")
Dim anotherWorksheet As ExcelWorksheet = excelPackage.Workbook.Worksheets.FirstOrDefault(Function(x) x.Name Is "SomeWorksheet")
Dim valA1 As String = firstWorksheet.Cells("A1").Value.ToString
Dim valB1 As String = firstWorksheet.Cells(1, 2).Value.ToString
excelPackage.Save()
End Using
Dim proc As Process
Try
proc = New Process()
Process.Start(filInf.FullName)
Catch ex As Exception
MsgBox("File cannot be opened", MsgBoxStyle.Information, "Cannot open file")
End Try
Catch
End Try
End Sub
Public Function GetFileToSave()
Dim strFilename As String = ""
SaveFileDialog1.Filter = "Excel Workbook (*.xlsx)|*.xlsx"
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
strFilename = SaveFileDialog1.FileName
Return strFilename
End If
End Function

How do I access the "Save Thumbnail" feature of Excel through Interop?

I'm working on an Excel add-in using C# and .NET 4.0. In Excel there's a feature in the Save-As dialog for saving a preview thumbnail along with the document. How can I access this feature in code? Also, how do I access the preview image (I think it's a bitmap) once it has been saved?
Currently my Excel add-in makes a copy of the document as follows:
Globals.ThisAddIn.Application.ActiveWorkbook.SaveCopyAs("tempwbcopy");
It then copies the document to a server and erases the temp file. Basically I'd like to also make the thumbail image, post it to the server, and erase the temp file.
I don't know how to access the Save Thumbnail feature programatically, but if you have a Excel file with a thumbnail and want to extract the image you could use the following code (using the OpenXml 2.0 API):
Private Sub ExtractThumbnailAsPng(ByVal pathToExcelFile As String, ByVal outputPath As String)
Dim thumbnailPart As DocumentFormat.OpenXml.Packaging.ThumbnailPart
Using excelFile As SpreadsheetDocument = SpreadsheetDocument.Open(pathToExcelFile, True)
thumbnailPart = excelFile.ThumbnailPart
If thumbnailPart IsNot Nothing Then
Using thumbnailStream As Stream = thumbnailPart.GetStream(FileMode.Open, FileAccess.ReadWrite)
Dim thumbBitmap As New Bitmap(thumbnailStream)
thumbBitmap.Save(outputPath, System.Drawing.Imaging.ImageFormat.Png)
End Using
End If
End Using
End Sub
Since this isn't Excel automation you could do this server side as well.

How can I create a table readable in excel? C#

I have some data in c#, and I want to put this data into Excel. I figure the easiest way is to export it as XML since Excel reads xml files.
What's the easiest way to do this? I don't know what format the xml needs to be in for Excel to read it. I want a simple table of data (headers, data, and totals, although the totals I can simply generate in c# rather than have excel do it).
There might also be a better way without using xml, but simplest is best and definitely no 3rd party stuff...
Ideas?
The easiest way is to dump data into a CSV format, and open it with Excel!
This can take 10 lines of code in Python.
I am sure you can figure this out:
http://en.wikipedia.org/wiki/Comma-separated_values
There's a nice intro at http://www.codeproject.com/KB/office/excelxmlspreadsheet.aspx that should get you started writing basic XML spreadsheets.
You may want to reconsider using 3rd party tools; there are some nice ones out there with good licenses that will make your life a lot easier.
I've used http://www.carlosag.net/Tools/ExcelXmlWriter/ previously to write simple data to an Excel spreadsheet. It outputs right into the Excel XML format you mention.
I've also had success using Apache POI HSSF, though not its most recent incarnation (it lacked Office 2007 support at the time). You can use IKVM to recompile the Java library into a .NET library, and you're good to go.
This article explains how to open an manipulate XML data in Excel 2003, and this video explains the same for 2007.
Or, as lpthnc has suggested, you can export the data as CSV which Excel has no problem handling.
Write a CSV reader writer if you want a good compromise between human and machine readable in a Windows environment
Loads into Excel too.
There's a discussion about it here:
http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.html
That is a C# article not a C one.
An alternate approach if your needs are basic: you can put it into HTML with a table representing your spreadsheet and just name your html file .xls. That way you don't need to worry about what a comma will do to you and can provide a basic level of formatting as well.
I have had to do similar things in the past. The easiest way I have found to do it is to export directly from my application to excel:
Microsoft.Office.Interop.Excel
Populate a datatable, datagrid, dataset, etc. and iteerate through the results and output to excel. The exmaple below is in VB but can be easily altered for your purposes and uses a dataset:
Public Sub ExcelExport(ByVal objDataSet As System.Data.DataSet)
Try
Dim l_ofd As New SaveFileDialog
l_ofd.Filter = "Microsoft 2007 Excel File (*.xls)|*.xls"
If (l_ofd.ShowDialog = System.Windows.Forms.DialogResult.OK) Then
If (objDataSet.Tables.Count > 0) Then
Dim myExcel As ApplicationClass = New ApplicationClass()
myExcel.Visible = _ShowWorkBook
Dim wb1 As Workbook = myExcel.Workbooks.Add("")
Dim ws1 As Worksheet = CType(wb1.Worksheets.Add, Microsoft.Office.Interop.Excel.Worksheet)
ws1.Name = _WorkSheetName
For indx As Integer = 0 To objDataSet.Tables(_DataSetName).Columns.Count - 1
ws1.Cells(1, indx + 1) = objDataSet.Tables(_DataSetName).Columns.Item(indx).ToString
Next
Dim rowID As Integer = 2
Dim dr As DataRow
For Each dr In objDataSet.Tables(_DataSetName).Rows
Dim colID As Integer = 1
Dim data As Object
For Each data In dr.ItemArray
ws1.Cells(rowID, colID) = data.ToString()
colID += 1
Next
rowID += 1
Next
Dim fileName As String = l_ofd.FileName
wb1.SaveAs(fileName)
wb1.Close()
myExcel.Workbooks.Close()
myExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel)
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws1)
System.Runtime.InteropServices.Marshal.ReleaseComObject(wb1)
ws1 = Nothing
wb1 = Nothing
myExcel = Nothing
Else
MessageBox.Show("No data present to export")
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try
End Sub
Here's an article that presents another approach using the OpenXML SDK 2.0:
http://openxmldeveloper.org/articles/7937.aspx
It demonstrates the use of ExtremeML - a 100% managed code extension library that greatly simplifies the programmatic creation of Excel content from .NET languages. The tutorial series covers a broad range of scenarios.
Disclaimer: I am the creator of ExtremeML.
if you have a DataTable, I just wrote some code to transfer it to Excel. First you need an Excel reference.
//Just a test DataTable
System.Data.DataTable table = new System.Data.DataTable();
table.Columns.AddRange(new DataColumn[] { new DataColumn("Col1"),new DataColumn("Col2") });
table.Rows.Add("row1col1", "row1col2");
table.Rows.Add("row2col1", "row2col2");
//create Excel Application
Microsoft.Office.Interop.Excel.ApplicationClass s = new ApplicationClass();
Workbook w = s.Workbooks.Add(""); //create new Workbook
Worksheet ws = w.ActiveSheet as Worksheet; //get active sheet.
//COPY COLUMN HEADERS
int startCol = 1;
int startRow = 1;
foreach (DataColumn col in table.Columns)
{
//copy columns in the first row
((Range)ws.Cells[startRow, startCol]).Value2 = col.ColumnName;
startCol++;
}
//COPY ROWS
startRow = 2; //start 2nd row
foreach (DataRow row in table.Rows)
{
startCol = 1;
foreach (DataColumn col in table.Columns)
{
((Range)ws.Cells[startRow, startCol]).Value2 = row[col].ToString();
startCol++;
}
startRow++;
}
//start EXCEL
s.Visible = true;

Categories