You will need the Office SDK . I leave it to your discretion to install it.
That said, the code may seem complex at first - until you know the structure of the files. I'll put it one step at a time.
To work with any Office files, we need the following namespaces:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
And for Excel, specifically:
using DocumentFormat.OpenXml.Spreadsheet;
You start by preparing a stream . The best way to do this is with a stream of memory, but you can use other forms also depending on your courage and willingness.
MemoryStream stream = new MemoryStream();
Now you create the object that will be the fact file. Note the use of the using
command. All the rest of the code should be within the block declared by the using.
using (SpreadsheetDocument foo = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
{
// você vai montar a estrutura do arquivo aqui.
}
An excel file is made up of work "books" ( workbooks ). Each book is an XML element that will contain spreadsheets. Let's insert them.
WorkbookPart workbookPart = foo.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
workbookPart.Workbook.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
Remember where the above code should be placed;)
Now we need to put the spreadsheets together. It's simple:
Sheets sheets = workbookPart.Workbook.AppendChild<Sheets>(new Sheets());
( sheet is an English spreadsheet)
Each worksheet you enter must have a unique, textual identifier. This identifier can be arbitrary. Since I already used the term foo
for the main object, I will use bar
for the key.
string idPlanilha = "bar";
And now we've added a spreadsheet itself. If you want to add more, the code is the same. Just change the key.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(idPlanilha);
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheet planilha1 = new Sheet()
{
Id = idPlanilha,
SheetId = 1, // incremente na próxima
Name = "minhaPrimeiraPlanilha"
};
sheets.Append(planilha1);
Now we already have a worksheet in the object that represents the file. You just have to fill it out. This is the coolest part.
Let's get a spreadsheet data set:
SheetData dadosPlanilha = worksheetPart.Worksheet.GetFirstChild<SheetData>();
Assuming you have a DataTable
called dados
. You can pass her data to the dataset in the worksheet as follows:
UInt32Value indice = 1;
foreach (DataRow rowDados in dados.Rows)
{
Row rowExcel = new Row()
{
RowIndex = indice
};
char letraColuna = 'A';
foreach (DataColumn column in dados.Columns)
{
object valorOriginal = rowDados[column];
string valorTratado = valorOriginal != null ? valorOriginal.ToString() : ""; // Sanitizaçãozinha básica
string coordenada = letraColuna.ToString() + indice.ToString();
Cell celula = new Cell()
{
CellReference = coordenada,
CellValue = new CellValue(valorTratado),
DataType = CellValues.String
};
rowExcel.Append(celula);
letraColuna = (char)(((int)letraColuna) + 1);
}
dadosPlanilha.Append(rowExcel);
indice++;
}
Note that we are passing all values of DataTable
to the worksheet as strings. Again I leave it to you to use other formats (for dates and numbers).
Now, we save everything and close the object representing the file.
worksheetPart.Worksheet.Save();
workbookPart.Workbook.Save();
foo.Close();
Do you know that stream that we opened to represent the file? It contains the binary file now! If it was a FileStream
, for example, the file would already be practically written now. Since we use MemoryStream
, we have the file in memory. You are now free to use it any way you like - I recommend doing just the following before writing to disk, saving to a database, or forcing a download:
stream.Position = 0;
Ah, just one more thing ... As the file format will be OOXML (in this case, anything .xlsx), you need Office at least 2013 to have full compatibility. But you should be able to open with Office from 2007 (if you are in a public branch that still has that version), or with other tools like Google Drive.
Ready. For today it's just, guys.