I have a code left by the previous developer. What I need to do is to change the background color and text color of the header columns in the Excel file. But I just couldn't. We use OpenXML. Heading columns are added as rows. I can't change background and text color of these header row. How can I change the background color of the cell interiors in the cell variable?
public byte[] analizVerileriExport(DataTable data)
{
byte[] result;
using (MemoryStream mem = new MemoryStream())
{
using (var spreadsheetDocument = SpreadsheetDocument.Create(mem, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
SheetData sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = string.IsNullOrEmpty(data.TableName) ? "Analiz Verileri" : data.TableName
};
Row headerRow = new Row();
List<excelColumns> columns = new List<excelColumns>();
foreach (DataColumn column in data.Columns)
{
columns.Add(new excelColumns() { columnName = column.ColumnName, columnDataType = column.DataType });
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in data.Rows)
{
Row newRow = new Row();
foreach (excelColumns col in columns)
{
Cell cell = new Cell();
cell.DataType = col.columnDataType.ToCellValue();
cell.CellValue = new CellValue(dsrow[col.columnName].ToString()); //
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
sheets.Append(sheet);
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}
result = mem.ToArray();
}
//string excelName = cmbClient.Text + " Kişisel Veri Envanteri " + String.Format("{0:dd_MM_yyyy HH-mm-ss}", DateTime.Now) + ".xlsx";
//openFile(excelName, result);
return result;
}
Related
I tried to create an excel with multiple sheets and different data count in both sheets. but when i tried to create only one row was getting added in both sheets and not more than that and when i open the excel it asks for repair.
`
MemoryStream ms = new MemoryStream();
SpreadsheetDocument xl = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);
byte[] dt = null;
// Add a WorkbookPart to the document
WorkbookPart workbookPart = xl.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
tracing.Trace("Temp Plugin Executed");
Sheets sheets = xl.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Begin: Code block for Excel sheet 1
WorksheetPart worksheetPart1 = workbookPart.AddNewPart<WorksheetPart>();
Worksheet workSheet1 = new Worksheet();
SheetData sheetData1 = new SheetData();
// the data for sheet 1
Row rowInSheet1 = new Row();
Cell emptyCell = CreateTextCell("A", "111", 1);
rowInSheet1.Append(emptyCell);
sheetData1.Append(rowInSheet1);
workSheet1.Append(sheetData1);
worksheetPart1.Worksheet = workSheet1;
Sheet sheet1 = new Sheet()
{
Id = xl.WorkbookPart.GetIdOfPart(worksheetPart1),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet1);
// End: Code block for Excel sheet 1
// Begin: Code block for Excel sheet 2
WorksheetPart worksheetPart2 = workbookPart.AddNewPart<WorksheetPart>();
Worksheet workSheet2 = new Worksheet();
SheetData sheetData2 = new SheetData();
// the data for sheet 2
Row rowInSheet2 = new Row();
Cell mycell = CreateTextCell("A", "data", 1);
Cell mycell1 = CreateTextCell("A", "data", 2);
rowInSheet2.Append(mycell);
rowInSheet2.Append(mycell1);
sheetData2.Append(rowInSheet2);
workSheet2.Append(sheetData2);
worksheetPart2.Worksheet = workSheet2;
Sheet sheet2 = new Sheet()
{
Id = xl.WorkbookPart.GetIdOfPart(worksheetPart2),
SheetId = 2,
Name = "Sheet2"
};
sheets.Append(sheet2);
xl.Close();
dt = ms.ToArray();
public Cell CreateTextCell(string header, string text, int index)
{
//Create a new inline string cell.
Cell c = new Cell();
c.DataType = CellValues.InlineString;
c.CellReference = header + index;
//Add text to the text cell.
InlineString inlineString = new InlineString();
Text t = new Text();
t.Text = text;
inlineString.AppendChild(t);
c.AppendChild(inlineString);
return c;
}
`
I tried creating multiple sheets with different data count on both sheets
The second cell should be B1 not A2. It's the second cell in the first row. That's how Excel works. So the code should look like:
Cell mycell = CreateTextCell("A", "data", 1);
Cell mycell1 = CreateTextCell("B", "data2", 1);
To add a second row on the second worksheet:
// the data for sheet 2
Row row2InSheet2 = new Row() { RowIndex = 2 };
sheetData2.Append(row2InSheet2);
// In the new row, find the column location to insert a cell in A2.
Cell refCell = null;
foreach (Cell cell in row2InSheet2.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, "A2", true) > 0)
{
refCell = cell;
break;
}
}
Cell mycellRow21 = CreateTextCell("A", "new_row_test1", 2);
row2InSheet2.InsertBefore(mycellRow21, refCell);
You can study the Microsoft documentation on OpenXml for more examples
I was trying to create an excel using Memory Stream. Here is the code I'm trying,
using (MemoryStream mem = new MemoryStream())
{
using (var sheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook))
{
//// Add a WorkbookPart to the document.
WorkbookPart workbookpart = sheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorkbookStylesPart workbookstyle = workbookpart.AddNewPart<WorkbookStylesPart>();
workbookstyle.Stylesheet = this.GenerateStyleSheet();
workbookstyle.Stylesheet.Save();
//// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Columns cols = new Columns();
Column col = new Column();
col.BestFit = true;
col.CustomWidth = true;
col.Width = 22.33;
col.Max = 13;
col.Min = 1;
cols.Append(col);
worksheetPart.Worksheet.Append(cols);
SheetData sheetData = new SheetData();
worksheetPart.Worksheet.Append(sheetData);
//// Add Sheets to the Workbook.
Sheets sheets = sheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
//// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = sheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
sheets.Append(sheet);
workbookpart.Workbook.Save();
List<string> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
}
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = this.CreateHeaderRow(columns);
sheetData.AppendChild(headerRow);
foreach (DataRow dataSetRow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = this.CreateDataRow(dataSetRow);
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
var result = mem.ToArray();
System.IO.File.WriteAllBytes(fileName, result);
}
An excel file is getting created, but when I try to open it, I'm getting an error as bellow
If I press yes, it says
The workbook cannot be opened or repaired by Microsoft Excel because
it is corrupt
How can I fix this?
Thanks to #zaikhan's comment, I was able to fix my issue. When I closed the sheetDocument it worked.
using (MemoryStream mem = new MemoryStream())
{
using (var sheetDocument = SpreadsheetDocument.Create(mem, SpreadsheetDocumentType.Workbook))
{
//// Add a WorkbookPart to the document.
WorkbookPart workbookpart = sheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
WorkbookStylesPart workbookstyle = workbookpart.AddNewPart<WorkbookStylesPart>();
workbookstyle.Stylesheet = this.GenerateStyleSheet();
workbookstyle.Stylesheet.Save();
//// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Columns cols = new Columns();
Column col = new Column();
col.BestFit = true;
col.CustomWidth = true;
col.Width = 22.33;
col.Max = 13;
col.Min = 1;
cols.Append(col);
worksheetPart.Worksheet.Append(cols);
SheetData sheetData = new SheetData();
worksheetPart.Worksheet.Append(sheetData);
//// Add Sheets to the Workbook.
Sheets sheets = sheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
//// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = sheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
sheets.Append(sheet);
workbookpart.Workbook.Save();
List<string> columns = new List<string>();
foreach (DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
}
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = this.CreateHeaderRow(columns);
sheetData.AppendChild(headerRow);
foreach (DataRow dataSetRow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = this.CreateDataRow(dataSetRow);
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
sheetDocument.Close();
}
var result = mem.ToArray();
System.IO.File.WriteAllBytes(fileName, result);
}
I inserted/appended new sheet in existing Excel file using open XML but I am not able to add rows and cell values. Following is my code:
using (var workbook = SpreadsheetDocument.Open(excelFilePath, true))
{
var workbookPart = workbook.WorkbookPart;
var wb = workbookPart.Workbook;
int rowIndex = 0;
// Add a blank WorksheetPart.
WorksheetPart newWorksheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(newWorksheetPart);
// Get a unique ID for the new worksheet.
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
// Give the new worksheet a name.
string sheetName = "Data";
// Append the new worksheet and associate it with the workbook.
Sheet dataSheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
sheets.Append(sheet);
workbookPart.Workbook.Save();
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
Row headerRow = new Row();
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue("EmpId");
headerRow.AppendChild<Cell>(cell);
cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue("Name");
headerRow.AppendChild<Cell>(cell);
headerRow.AppendChild<Cell>(cell);
dataSheet.InsertAt<Row>(headerRow, rowIndex++);
workbookPart.Workbook.Save();
}
}
It's throwing an exception:
Non-composite elements do not have child elements.
When i got this error ("Non-composite elements do not have child elements.") was about my sheet object. I got the worng object to Apeend, so you need change the use .Append to something like that:
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
sheetData.Append(row);
A Full Example
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(tmp, SpreadsheetDocumentType.Workbook))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = fileName,
};
sheets.Append(sheet);
var firstChild = sheet.FirstChild;
//sheet.Append(row);
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
UInt32 rowIndex = 1;
var row = new Row() { RowIndex = rowIndex };
var firstNameCell = new Cell() { CellReference = "A" + rowIndex };
firstNameCell.CellValue = new CellValue("FirstName");
firstNameCell.DataType = CellValues.String;
row.Append(firstNameCell);
Cell lastNameCell = new Cell() { CellReference = "B" + rowIndex };
lastNameCell.CellValue = new CellValue("LastName");
lastNameCell.DataType = new EnumValue<CellValues>(CellValues.String);
row.Append(lastNameCell);
sheetData.Append(row);
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}
How can we able to write next row of the excel sheet if it ave records during exporting data from c#
it is the code i used for exporting data. to excel . i failed to export the data to next line by this code
private void ExportToOxml(bool firstTime)
{
if (count == 0)
{
ResultsData.Columns.Remove("TotalRecords");
ResultsData.Columns.Remove("PageIndex");
// fileName = #"C:\MyExcel.csv";
//Delete the file if it exists.
if (firstTime && File.Exists(xsfd.FileName))
{
File.Delete(fileName);
}
count++;
}
if (firstTime)
{
//This is the first time of creating the excel file and the first sheet.
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.
Create(fileName, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
var bold1 = new System.Windows.Documents.Bold();
CellFormat cf = new CellFormat();
// Add Sheets to the Workbook.
Sheets sheets;
sheets = spreadsheetDocument.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = sheetId,
Name = "Sheet" + sheetId
};
sheets.Append(sheet);
//Add Header Row.
var headerRow = new Row();
foreach (DataColumn column in ResultsData.Columns)
{
var cell = new Cell { DataType = CellValues.String, CellValue = new CellValue(column.ColumnName) };
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow row in ResultsData.Rows)
{
var newRow = new Row();
foreach (DataColumn col in ResultsData.Columns)
{
var cell = new Cell
{
DataType = CellValues.String,
CellValue = new CellValue(row[col].ToString())
};
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
spreadsheetDocument.Close();
}
else
{
// Open the Excel file that we created before, and start to add sheets to it.
var spreadsheetDocument = SpreadsheetDocument.Open(fileName, true);
var workbookpart = spreadsheetDocument.WorkbookPart;
if (workbookpart.Workbook == null)
workbookpart.Workbook = new Workbook();
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
var sheets = spreadsheetDocument.WorkbookPart.Workbook.Sheets;
if (sheets.Elements<Sheet>().Any())
{
//Set the new sheet id
sheetId = sheets.Elements<Sheet>().Max(s => s.SheetId.Value) + 1;
}
else
{
sheetId = 1;
}
// Append a new worksheet and associate it with the workbook.
var sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = sheetId,
Name = "Sheet" + sheetId
};
sheets.Append(sheet);
//Add the header row here.
var headerRow = new Row();
foreach (DataColumn column in ResultsData.Columns)
{
var cell = new Cell { DataType = CellValues.String, CellValue = new CellValue(column.ColumnName) };
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow row in ResultsData.Rows)
{
var newRow = new Row();
foreach (DataColumn col in ResultsData.Columns)
{
var cell = new Cell
{
DataType = CellValues.String,
CellValue = new CellValue(row[col].ToString())
};
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Close();
}
}
I am currently creating an Excel Sheet in a console application for testing purposes. I need to implement my code in an ASP.Net .aspx page.
How can I offer this Excel sheet to the user for download without saving it in any form locally?
This is my code:
static void Main(string[] args)
{
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(DateTime.Now.ToString("ddMMyyyyHHmmss") + #".xlsx", SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet()
{
Id = spreadsheetDocument.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheet"
};
sheets.Append(sheet);
Cell cell = InsertCellInWorksheet("A", 1, worksheetPart);
cell.CellValue = new CellValue("23.289374");
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
Cell cellString = InsertCellInWorksheet("B", 1, worksheetPart);
cellString.CellValue = new CellValue("hello");
cellString.DataType = new EnumValue<CellValues>(CellValues.String);
// Close the document.
workbookpart.Workbook.Save();
spreadsheetDocument.Close();
}
// Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet.
// If the cell already exists, returns it.
private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = columnName + rowIndex;
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
else
{
row = new Row() { RowIndex = rowIndex };
sheetData.Append(row);
}
// If there is not a cell with the specified column name, insert one.
if (row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0)
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First();
}
else
{
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, cellReference, true) > 0)
{
refCell = cell;
break;
}
}
Cell newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
worksheet.Save();
return newCell;
}
}
Use a MemoryStream. e.g.
public MemoryStream CreateSpreadSheet()
{
MemoryStream mem = new MemoryStream();
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.
Create(mem, SpreadsheetDocumentType.Workbook);
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Code omitted for brevity....
// Close the document.
workbookpart.Workbook.Save();
spreadsheetDocument.Close();
return mem;
}
You will then need to do something like this in the code behind of your aspx page:
using (MemoryStream mem = new CreateSpreadSheet(mem))
{
Response.Clear();
Response.ContentType =
#"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
Response.AddHeader("content-disposition", "attachment;filename=name_your_file.xlsx");
mem.WriteTo(Response.OutputStream);
Response.End();
}