Write IEnumerable<object> to Excel, File isn't editable in Excel web - c#

I have written this class to write a collection of any type to an excel file:
public static class ExcelWriter
{
public static void WriteToExcelFile(IEnumerable<object> collection, string filePath)
{
if (collection?.Any() != true || String.IsNullOrWhiteSpace(filePath))
return;
if (File.Exists(filePath))
File.Delete(filePath);
using (var document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
sheetData.AppendChild(generateHeaderRow(collection.First().GetType()));
foreach (var item in collection)
{
sheetData.AppendChild(generateValuesRow(item));
}
worksheetPart.Worksheet.Save();
}
}
private static Row generateHeaderRow(Type dataType)
{
var propertyNames = dataType.GetProperties().Select(p => p.Name).ToList();
var headerCells = new Cell[propertyNames.Count];
for (int i = 0; i < propertyNames.Count; i++)
{
headerCells[i] = createCell(propertyNames[i], CellValues.String);
}
return new Row(headerCells);
}
private static Row generateValuesRow(object rowData)
{
var cells = new List<Cell>();
foreach (var property in rowData.GetType().GetProperties())
{
var propertyValue = property.GetValue(rowData);
cells.Add(createCell(propertyValue.ToString(), getCellValueByType(propertyValue)));
}
return new Row(cells);
}
private static CellValues getCellValueByType(object propertyValue)
{
string propertyValueString = propertyValue.ToString();
if (Double.TryParse(propertyValueString, out _))
{
return CellValues.Number;
}
if (DateTime.TryParse(propertyValueString, out _))
{
return CellValues.Date;
}
if (Boolean.TryParse(propertyValueString, out _))
{
return CellValues.Boolean;
}
return CellValues.String;
}
private static Cell createCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
};
}
}
This actually generates the excel file, but when I open that file in Excel web it opens in Viewing mode and says you need to repair it, in order to edit(Excel can't repair it though):
I changed my code to work with a specific type and it worked without this issue. That code looks like this:
public class TypeDependentWriter
{
public static void WriteToExcelFile(IEnumerable<TestDataType> collection, string filePath)
{
if (collection?.Any() != true || String.IsNullOrWhiteSpace(filePath))
return;
if (File.Exists(filePath))
File.Delete(filePath);
using (var document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "Sheet1"
};
sheets.Append(sheet);
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
// Header row.
Row row = new Row();
row.Append(
createCell("Id", CellValues.String),
createCell("Name", CellValues.String),
createCell("Birth Date", CellValues.String));
sheetData.AppendChild(row);
// Data rows.
foreach (var item in collection)
{
row = new Row();
row.Append(
createCell(item.Id.ToString(), CellValues.Number),
createCell(item.Name, CellValues.String),
createCell(item.DateOfBirth.ToString("yyyy/MM/dd"), CellValues.String));
sheetData.AppendChild(row);
}
worksheetPart.Worksheet.Save();
}
}
private static Cell createCell(string value, CellValues dataType)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
};
}
}
How can I make the first code work?

The reason my second code wasn't generating the issue was this part:
row.Append(
createCell(item.Id.ToString(), CellValues.Number),
createCell(item.Name, CellValues.String),
createCell(item.DateOfBirth.ToString("yyyy/MM/dd"), CellValues.String /* I'm using string for DateTime here. */));
I figured out that I should:
use CellValues.Number for dates.
and call .ToOADate() extension method on the DateTime variable before calling ToString().
I should define a cell style and apply that style to the cells that store dates.
So I'm now creating date cells this way:
var dateCell = new Cell()
{
CellValue = new CellValue(((DateTime)propertyValue).ToOADate()
.ToString(CultureInfo.InvariantCulture)),
DataType = new EnumValue<CellValues>(CellValues.Number),
StyleIndex = 1 /* Style index for date cells */
}
And the style for date cells can be defined this way(I took this from Dave Williams post):
var CellFormats = new CellFormats();
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 14,
FormatId = 0,
ApplyNumberFormat = true
});
CellFormats.Count = (uint)CellFormats.ChildElements.Count;
var StyleSheet = new Stylesheet();
StyleSheet.Append(CellFormats);
But if you don't have any other defined Fill, Font... this is not going to work because we're using FillId = 0, etc. which we haven't defined, a minimum style you can define to get this work also can be found on Dave Williams post:
private static Stylesheet GetStylesheet()
{
var StyleSheet = new Stylesheet();
// Create "fonts" node.
var Fonts = new Fonts();
Fonts.Append(new Font()
{
FontName = new FontName() { Val = "Calibri" },
FontSize = new FontSize() { Val = 11 },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
});
Fonts.Count = (uint)Fonts.ChildElements.Count;
// Create "fills" node.
var Fills = new Fills();
Fills.Append(new Fill()
{
PatternFill = new PatternFill() { PatternType = PatternValues.None }
});
Fills.Append(new Fill()
{
PatternFill = new PatternFill() { PatternType = PatternValues.Gray125 }
});
Fills.Count = (uint)Fills.ChildElements.Count;
// Create "borders" node.
var Borders = new Borders();
Borders.Append(new Border()
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
Borders.Count = (uint)Borders.ChildElements.Count;
// Create "cellStyleXfs" node.
var CellStyleFormats = new CellStyleFormats();
CellStyleFormats.Append(new CellFormat()
{
NumberFormatId = 0,
FontId = 0,
FillId = 0,
BorderId = 0
});
CellStyleFormats.Count = (uint)CellStyleFormats.ChildElements.Count;
// Create "cellXfs" node.
var CellFormats = new CellFormats();
// A default style that works for everything but DateTime
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 0,
FormatId = 0,
ApplyNumberFormat = true
});
// A style that works for DateTime (just the date)
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 14, // or 22 to include the time
FormatId = 0,
ApplyNumberFormat = true
});
CellFormats.Count = (uint)CellFormats.ChildElements.Count;
// Create "cellStyles" node.
var CellStyles = new CellStyles();
CellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0,
BuiltinId = 0
});
CellStyles.Count = (uint)CellStyles.ChildElements.Count;
// Append all nodes in order.
StyleSheet.Append(Fonts);
StyleSheet.Append(Fills);
StyleSheet.Append(Borders);
StyleSheet.Append(CellStyleFormats);
StyleSheet.Append(CellFormats);
StyleSheet.Append(CellStyles);
return StyleSheet;
}

Related

Adding Table to openxml spreadsheet causes excel to repair workbook when opening

I'm working on a small excel export. All the data is there but adding a spreadsheet table for the range in question to provide quick and easy access to sort&filter when the user opens the file in excel causes a problem. The problem is that when the file is opened in excel we found a problem with some content in... and a query if they should try to recover as much as we can.
After repairing it excel states that it was able to open the file by repairing or removing the unreadable content. with Repaired Records: Table from /xl/tables/table1.xml part (Table) listed in a text field below. After this the workbook behaves as I intended, with a table.
I have searched and tried almost everything I've stumbled upon. This SO question is very similar but the proposed answer does not work for me.
A minimal example with the problem is here. It generates two excel files, one with the table added and one without. The one without is previewable in Explorer, the problematic one displays the message:
The file can't be previewed because of an error in the Microsoft Excel previewer.
Nuget used: DocumentFormat.OpenXml version 2.14.0. Excel version is office365, desktop version. Running under Windows 10.
What I have tried:
Various openxml validation tools, no errors found
Saved the (by excel) repaired file and compared the content of those two. I don't find any difference that in my head can serve as an explanation
It would be very nice to have the table already in place when the excel file is generated.
Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using ExcelGenerator;
namespace ConsoleAppOpenXmlSpreadsheetWithTable
{
class Program
{
static void Main(string[] args)
{
var headerRow = new List<string> { "Company", "Country", "Fruit" };
var exportRowList = new List<ExcelExportRow>();
exportRowList.Add(new ExcelExportRow() { Company ="Spanish Oranges A", Country = "Spain", Fruit ="Oranges"});
exportRowList.Add(new ExcelExportRow() { Company = "Mexican Oranges Ltd", Country = "Mexico", Fruit = "Oranges" });
exportRowList.Add(new ExcelExportRow() { Company = "Medit. Bananas", Country = "Spain", Fruit = "Bananas" });
exportRowList.Add(new ExcelExportRow() { Company = "Mexican Bananas", Country = "Mexico", Fruit = "Bananas" });
exportRowList.Add(new ExcelExportRow() { Company = "Mexican Sweet Oranges", Country = "Mexico", Fruit = "Oranges" });
using (var memoryStream = ExcelFileGenerator.GenerateArticleListWithImagesExcelFile(headerRow, exportRowList, false))
{
using (var fileStream = new FileStream("OpenXmlSpreadsheet.xlsx", FileMode.Create))
{
memoryStream.CopyTo(fileStream);
}
}
using (var memoryStream = ExcelFileGenerator.GenerateArticleListWithImagesExcelFile(headerRow, exportRowList, true))
{
using (var fileStream = new FileStream("OpenXmlSpreadsheetWithTable.xlsx", FileMode.Create))
{
memoryStream.CopyTo(fileStream);
}
}
}
}
}
ExcelFileGenerator.cs
using System;
using System.Collections.Generic;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace ExcelGenerator
{
public class ExcelExportRow
{
public string Company { get; set; }
public string Country { get; set; }
public string Fruit { get; set; }
}
public static class ExcelFileGenerator
{
private const int normalFontStyleIndex = 0;
private const int boldFontStyleIndex = 1;
public static MemoryStream GenerateArticleListWithImagesExcelFile(List<string> headerRow, List<ExcelExportRow> excelExportRoListw, bool insertTable)
{
MemoryStream memoryStream = new MemoryStream();
using (SpreadsheetDocument document = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
Workbook workbook = new Workbook();
workbookPart.Workbook = workbook;
WorkbookStylesPart workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>("rIdStyles");
Stylesheet stylesheet = StyleSheet();
workbookStylesPart.Stylesheet = stylesheet;
workbookStylesPart.Stylesheet.Save();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
Worksheet worksheet = new Worksheet();
SheetData sheetData = new SheetData();
Sheets sheets = new Sheets();
//get the string name of the columns
string[] excelColumnNamesTitle = new string[5];
for (int n = 0; n < 5; n++)
excelColumnNamesTitle[n] = GetExcelColumnName(n);
var columns = new Columns();
columns.Append(new Column() { Min = 1, Max = 1, CustomWidth = true, Width = 24 });
columns.Append(new Column() { Min = 2, Max = 3, CustomWidth = true, Width = 12 });
worksheet.Append(columns);
if (excelExportRoListw is not null)
{
Row rowTitle = new Row() { RowIndex = (UInt32Value)1 };
for (int c = 0; c < headerRow.Count; c++)
{
AppendTextCell(excelColumnNamesTitle[c], headerRow[c], rowTitle, boldFontStyleIndex);
}
sheetData.Append(rowTitle);
uint rowNumber = 2;
foreach (var excelExportRow in excelExportRoListw)
{
var spreadsheetRow = new Row() { RowIndex = (UInt32Value)rowNumber };
AppendTextCell(excelColumnNamesTitle[0], excelExportRow.Company, spreadsheetRow, normalFontStyleIndex);
AppendTextCell(excelColumnNamesTitle[2], excelExportRow.Country, spreadsheetRow, normalFontStyleIndex);
AppendTextCell(excelColumnNamesTitle[3], excelExportRow.Fruit, spreadsheetRow, normalFontStyleIndex);
sheetData.Append(spreadsheetRow);
rowNumber++;
}
worksheet.Append(sheetData);
worksheetPart.Worksheet = worksheet;
}
// Table
if (insertTable)
DefineTable(worksheetPart, 1, 1 + excelExportRoListw.Count, 0, 2);
// Wrap up and save
worksheetPart.Worksheet.Save();
Sheet sheet = new Sheet() { Name = "Export", SheetId = (UInt32Value)1, Id = workbookPart.GetIdOfPart(worksheetPart) };
sheets.Append(sheet);
workbook.Append(sheets);
workbook.Save();
document.Close();
}
memoryStream.Position = 0;
return memoryStream;
}
private static void DefineTable(WorksheetPart worksheetPart, int rowMin, int rowMax, int colMin, int colMax)
{
#region Table
string rangeReference = $"{GetExcelColumnName(colMin)}{rowMin}:{GetExcelColumnName(colMax)}{rowMax}";
int tableNo = 1;
Table table = new Table()
{
Id = (UInt32)tableNo,
Name = "Table" + tableNo,
DisplayName = "Table" + tableNo,
Reference = rangeReference,
TotalsRowShown = false
};
AutoFilter autoFilter = new AutoFilter() { Reference = rangeReference };
TableColumns tableColumns = new TableColumns() { Count = (UInt32)(colMax - colMin + 1) };
for (int i = 0; i < (colMax - colMin + 1); i++)
{
tableColumns.Append(new TableColumn() { Id = (UInt32)(i + 1), Name = "Column" + i });
}
TableStyleInfo tableStyleInfo = new TableStyleInfo()
{
Name = "TableStyleMedium1",
ShowFirstColumn = false,
ShowLastColumn = false,
ShowRowStripes = true,
ShowColumnStripes = false
};
table.Append(autoFilter);
table.Append(tableColumns);
table.Append(tableStyleInfo);
#endregion
string tableRefId = "rIdTable1";
// Add table to worksheet - two different things implictly linked by using the same refId
TableDefinitionPart tableDefinitionPart = worksheetPart.AddNewPart<TableDefinitionPart>(tableRefId);
tableDefinitionPart.Table = table;
TableParts tableParts = new TableParts();
TablePart tablePart = new TablePart() { Id = tableRefId };
tableParts.Append(tablePart);
tableParts.Count = 1;
worksheetPart.Worksheet.Append(tableParts);
}
#region Excel Helper funcs
private static void AppendTextCell(string cellReference, string cellStringValue, Row excelRow, UInt32Value styleIndex)
{
// Add a new Excel Cell to our Row
Cell cell = new Cell() { CellReference = cellReference, DataType = CellValues.String };
CellValue cellValue = new CellValue();
cellValue.Text = cellStringValue;
cell.StyleIndex = styleIndex;
cell.Append(cellValue);
excelRow.Append(cell);
}
private static string GetExcelColumnName(int columnIndex)
{
if (columnIndex < 26)
return ((char)('A' + columnIndex)).ToString();
char firstChar = (char)('A' + (columnIndex / 26) - 1);
char secondChar = (char)('A' + (columnIndex % 26));
return string.Format("{0}{1}", firstChar, secondChar);
}
#endregion Helper funcs
#region Stylesheet
private static Stylesheet StyleSheet()
{
Stylesheet styleSheet = new Stylesheet();
Fonts fonts = new Fonts();
// 0 - normal fonts
Font myFont = new Font()
{
FontSize = new FontSize() { Val = 11 },
Color = new Color() { Rgb = HexBinaryValue.FromString("FF000000") },
FontName = new FontName() { Val = "Arial" }
};
fonts.Append(myFont);
//1 - font bold
myFont = new Font()
{
Bold = new Bold(),
FontSize = new FontSize() { Val = 11 },
Color = new Color() { Rgb = HexBinaryValue.FromString("FF000000") },
FontName = new FontName() { Val = "Arial" }
};
fonts.Append(myFont);
Fills fills = new Fills();
//default fill
Fill fill = new Fill()
{
PatternFill = new PatternFill() { PatternType = PatternValues.None }
};
fills.Append(fill);
Borders borders = new Borders();
//normal borders
Border border = new Border()
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
};
borders.Append(border);
CellFormats cellFormats = new CellFormats();
//0- normalFontStyleIndex for normal cells
CellFormat cellFormat = new CellFormat()
{
FontId = 0,
FillId = 0,
BorderId = 0,
ApplyFill = false
};
cellFormats.Append(cellFormat);
//1 - boldFontStyleIndex for header row
cellFormat = new CellFormat()
{
FontId = 1,
FillId = 0,
BorderId = 0,
ApplyFill = false
};
cellFormats.Append(cellFormat);
styleSheet.Append(fonts);
styleSheet.Append(fills);
styleSheet.Append(borders);
styleSheet.Append(cellFormats);
TableStyles tableStyles = new TableStyles()
{
Count = 0,
DefaultTableStyle = "TableStyleMedium1",
DefaultPivotStyle = "PivotStyleLight16"
};
styleSheet.Append(tableStyles);
return styleSheet;
}
#endregion Stylesheet
}
}

How to add colour to particular excel columns based on conditions using openxml?

I'm generating an excel sheet and I want to color the excel columns based on conditions. Now my all excel columns get red colors. I want to color only particular column names.
I'm using open XML for generating excel, is there any way to find the cells to apply color
using (SpreadsheetDocument document = SpreadsheetDocument.Create(path, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Template" };
sheets.Append(sheet);
var stylesheet = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
stylesheet.AddNamespaceDeclaration("mc", "http: //schemas.openxmlformats.org/markup-compatibility/2006");
stylesheet.AddNamespaceDeclaration("x14ac", "http: //schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
var fills = new Fills() { Count = 5U };
var fonts = new Fonts() { Count = 1U, KnownFonts = true };
// var cellFormats = new CellFormats();
Font font = new Font();
font.Append(new Color() { Rgb = "ff0000" });
fonts.Append(font);
// cellFormats.AppendChild(new CellFormat() { FontId = 0U });
stylesheet.Append(fonts);
stylesheet.Append(fills);
//stylesheet.Append(cellFormats);
//stylesheet.Append(fill);
var stylePart = workbookPart.AddNewPart<WorkbookStylesPart>();
stylePart.Stylesheet = stylesheet;
stylePart.Stylesheet.Save();
workbookPart.Workbook.Save();
SheetData sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
// Constructing header
Row row = new Row();
foreach (DataExchangeDefinition a in importColList)
{
defnExist = true;
if (a.MustFieldYN == true)
{
row.Append(
ConstructCell(a.FieldCaption, CellValues.String));
}
else
{
row.Append(
ConstructCell(a.FieldCaption, CellValues.String));
}
}
if (defnExist == false)
{
row.Append(
ConstructCell("Excel Template Definition Missing", CellValues.String));
}
// Insert the header row to the Sheet Data
sheetData.AppendChild(row);
// Inserting each employee
worksheetPart.Worksheet.Save();
}
Here is construct cell method
private Cell ConstructCell(string value, CellValues dataType)
{
Cell c = new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType)
//StyleIndex=0U
};
return c;
}
Is there any way to solve this?
1) Add style sheet to your WorkBookPart
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorkbookStylesPart stylePart = workbookPart.AddNewPart<WorkbookStylesPart>();
stylePart.Stylesheet = GenerateStylesheet();
stylePart.Stylesheet.Save();
Note: Add above WorkbookStylesPart code just below the WorkbookPart otherwise you can't get it to work.
2) Add below function that return stylesheet,
private Stylesheet GenerateStylesheet()
{
Stylesheet styleSheet = null;
Fonts fonts = new Fonts(
new Font( // Index 0 - default
new FontSize() { Val = 10 }
),
new Font( // Index 1 - header
new FontSize() { Val = 10 },
new Bold(),
new Color() { Rgb = "FFFFFF" }
));
Fills fills = new Fills(
new Fill(new PatternFill() { PatternType = PatternValues.None }), // Index 0 - default
new Fill(new PatternFill() { PatternType = PatternValues.Gray125 }), // Index 1 - default
new Fill(new PatternFill(new ForegroundColor { Rgb = new HexBinaryValue() { Value = "66666666" } })
{ PatternType = PatternValues.Solid }) // Index 2 - header
);
Borders borders = new Borders(
new Border(), // index 0 default
new Border( // index 1 black border
new LeftBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
new RightBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
new TopBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
new BottomBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
new DiagonalBorder())
);
CellFormats cellFormats = new CellFormats(
new CellFormat(), // default
new CellFormat { FontId = 0, FillId = 0, BorderId = 1, ApplyBorder = true }, // body
new CellFormat { FontId = 1, FillId = 2, BorderId = 1, ApplyFill = true } // header
);
styleSheet = new Stylesheet(fonts, fills, borders, cellFormats);
return styleSheet;
}
3) And your ConstructCell method,
private Cell ConstructCell(string value, CellValues dataType, uint styleIndex = 0)
{
return new Cell()
{
CellValue = new CellValue(value),
DataType = new EnumValue<CellValues>(dataType),
StyleIndex = styleIndex
};
}
4) And call your above method like
If you dont want to apply style then use below
ConstructCell(a.FieldCaption, CellValues.String));
And if you want to apply style on body cell then use below
ConstructCell(a.FieldCaption, CellValues.String, 1);
And if you want to apply style on header cell then use below
ConstructCell(a.FieldCaption, CellValues.String, 2);

Filling a cell with a solid color, using OpenXML that preserves otherwise existing sheet format

The following takes the format of existing sheet sSheet and creates a red font (along with some timestamp content) at A19:
using (SpreadsheetDocument document = SpreadsheetDocument.Open(sPath, true)) {
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sSheet);
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.FirstOrDefault().Id);
Worksheet worksheet = worksheetPart.Worksheet;
WorkbookStylesPart styles = document.WorkbookPart.WorkbookStylesPart;
Stylesheet stylesheet = styles.Stylesheet;
CellFormats cellformats = stylesheet.CellFormats;
Fonts fonts = stylesheet.Fonts;
UInt32 fontIndex = fonts.Count;
UInt32 formatIndex = cellformats.Count;
Cell cell = GetCell(worksheet, "A", 19);
cell.CellValue = new CellValue(DateTime.Now.ToLongTimeString());
cell.DataType = new EnumValue<CellValues>(CellValues.String);
CellFormat f = (CellFormat)cellformats.ElementAt((int)cell.StyleIndex.Value);
var font = (Font)fonts.ElementAt((int)f.FontId.Value);
var newfont = (Font)font.Clone();
newfont.Color = new Color() { Rgb = new HexBinaryValue("ff0000") };
fonts.Append(newfont);
CellFormat newformat = (CellFormat)f.Clone();
newformat.FontId = fontIndex;
cellformats.Append(newformat);
stylesheet.Save();
cell.StyleIndex = formatIndex;
worksheetPart.Worksheet.Save();
document.WorkbookPart.Workbook.Save();
document.Close();
}
But I can't make it create a solid fill. I tried adding
Fills fills = stylesheet.Fills; underneath Fonts fonts = stylesheet.Fonts;, as well as adding some wording that uses similar Fill language underneath the
var font = (Font)fonts.ElementAt((int)f.FontId.Value);
var newfont = (Font)font.Clone();
newfont.Color = new Color() { Rgb = new HexBinaryValue("ff0000") };
fonts.Append(newfont);
...as well as a lot of variations to it, but nothing compiled. I cannot figure out how to add a solid color fill. Any help is much appreciated. Thank you.
I obtained the code that follows by creating two basically "empty" workbooks, one with a cell having the background color, the other with no background color. I then opened the latter using the Open XML SDK Productivity Tool and used it to compare with the workbook having a background fill. This yields the code to turn the one into the other.
As you can see, it's necessary to create a new Fill with PatternFill, BackgroundColor and ForegroundColorelements. This is added to the list ofCellFormats` so that it can be referenced by the cell on the worksheet.
private void btnAddFillColor_Click(object sender, EventArgs e)
{
string filePath = "C:\\Test\\OpenXMLTest_NoFillColor.xlsx";
using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, true))
{
WorkbookPart wbPart = document.WorkbookPart;
WorksheetPart wsPart = wbPart.WorksheetParts.FirstOrDefault();
WorkbookStylesPart stylesPart = document.WorkbookPart.WorkbookStylesPart;
ChangeWorkbookStylesPart(stylesPart);
ChangeWorksheetPart(wsPart);
}
}
private void ChangeWorkbookStylesPart(WorkbookStylesPart workbookStylesPart1)
{
xl.Stylesheet stylesheet1 = workbookStylesPart1.Stylesheet;
xl.Fills fills1 = stylesheet1.GetFirstChild<xl.Fills>();
xl.CellFormats cellFormats1 = stylesheet1.GetFirstChild<xl.CellFormats>();
fills1.Count = (UInt32Value)3U;
xl.Fill fill1 = new xl.Fill();
xl.PatternFill patternFill1 = new xl.PatternFill() { PatternType = xl.PatternValues.Solid };
xl.ForegroundColor foregroundColor1 = new xl.ForegroundColor() { Rgb = "FFC00000" };
xl.BackgroundColor backgroundColor1 = new xl.BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill1.Append(foregroundColor1);
patternFill1.Append(backgroundColor1);
fill1.Append(patternFill1);
fills1.Append(fill1);
cellFormats1.Count = (UInt32Value)2U;
xl.CellFormat cellFormat1 = new xl.CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)2U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
cellFormats1.Append(cellFormat1);
}
private void ChangeWorksheetPart(WorksheetPart worksheetPart1)
{
xl.Worksheet worksheet1 = worksheetPart1.Worksheet;
xl.SheetData sheetData1 = worksheet1.GetFirstChild<xl.SheetData>();
xl.Row row1 = sheetData1.GetFirstChild<xl.Row>();
xl.Cell cell1 = row1.GetFirstChild<xl.Cell>();
cell1.StyleIndex = (UInt32Value)1U;
}
Generate a xlsx file by calling ExportDataSetToExcellWithColour_openXML(your_dataset, your_destination_file_full_path.xlsx). If the file exists, it will be deleted first.
No other third-party lib is used except OpenXML.
Your DataTable should be like:
column a, column b, column c, color
abc, def, ghi, #FF0000
aa1, bb2, ccc, #FFFF00
Data of the column 'color' should be a hex color code. The column 'color' will be removed in the destination xlsx file, and each line will be painted with the specified color.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;
......
public static void ExportDataSetToExcellWithColour_openXML(DataSet ds, string destination)
{
if (File.Exists(destination))
{
try
{
File.SetAttributes(destination, FileAttributes.Normal);
File.Delete(destination);
}
catch { }
}
using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
#region deal with color
List<string> colorCode = new List<string>();
foreach (global::System.Data.DataTable table in ds.Tables)
{
if (table.Columns.Contains("color"))
{
foreach (DataRow dr in table.Rows)
{
if (!colorCode.Contains(dr["color"].ToString()))
{
colorCode.Add(dr["color"].ToString());
}
}
}
}
WorkbookStylesPart stylePart = workbook.WorkbookPart.AddNewPart<WorkbookStylesPart>();
stylePart.Stylesheet = CreateStylesheet(colorCode);
//stylePart.Stylesheet = CreateStylesheet_ori();
stylePart.Stylesheet.Save();
#endregion
foreach (global::System.Data.DataTable table in ds.Tables)
{
DataTable ori_dt = null;
if (table.Columns.Contains("color"))
{
ori_dt = table.Clone();
foreach (DataRow dr in table.Rows)
{
ori_dt.Rows.Add(dr.ItemArray);
}
table.Columns.Remove("color");
}
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
{
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (global::System.Data.DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
int rowindex = 0;
foreach (global::System.Data.DataRow dsrow in table.Rows)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
if (ori_dt.Columns.Contains("color"))
{
try
{
cell.StyleIndex =
(
(UInt32)colorCode.FindIndex(
a => a == ori_dt.Rows[rowindex]["color"].ToString()
)
) + 1;
//cell.StyleIndex = (UInt32)2;
}
catch (Exception ex)
{
}
}
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
rowindex++;
}
}
}
}
public static Stylesheet CreateStylesheet(List<string> colorCode)
{
Stylesheet stylesheet1 = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
stylesheet1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
stylesheet1.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
DocumentFormat.OpenXml.Spreadsheet.Fonts fonts1 = new DocumentFormat.OpenXml.Spreadsheet.Fonts() { Count = (UInt32Value)1U, KnownFonts = true };
DocumentFormat.OpenXml.Spreadsheet.Font font1 = new DocumentFormat.OpenXml.Spreadsheet.Font();
DocumentFormat.OpenXml.Spreadsheet.FontSize fontSize1 = new DocumentFormat.OpenXml.Spreadsheet.FontSize() { Val = 11D };
DocumentFormat.OpenXml.Spreadsheet.Color color1 = new DocumentFormat.OpenXml.Spreadsheet.Color() { Theme = (UInt32Value)1U };
DocumentFormat.OpenXml.Spreadsheet.FontName fontName1 = new DocumentFormat.OpenXml.Spreadsheet.FontName() { Val = "Calibri" };
FontFamilyNumbering fontFamilyNumbering1 = new FontFamilyNumbering() { Val = 2 };
FontScheme fontScheme1 = new FontScheme() { Val = FontSchemeValues.Minor };
font1.Append(fontSize1);
font1.Append(color1);
font1.Append(fontName1);
font1.Append(fontFamilyNumbering1);
font1.Append(fontScheme1);
fonts1.Append(font1);
Fills fills1 = new Fills() { Count = (UInt32)(colorCode.Count + 2) };
// FillId = 0
Fill fill1 = new Fill();
PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.None };
fill1.Append(patternFill1);
fills1.Append(fill1);
// FillId = 1
Fill fill2 = new Fill();
PatternFill patternFill2 = new PatternFill() { PatternType = PatternValues.Gray125 };
fill2.Append(patternFill2);
fills1.Append(fill2);
foreach (string color in colorCode)
{
Fill fill5 = new Fill();
PatternFill patternFill5 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor3 = new ForegroundColor() { Rgb = color.Replace("#", "") };
BackgroundColor backgroundColor3 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill5.Append(foregroundColor3);
patternFill5.Append(backgroundColor3);
fill5.Append(patternFill5);
fills1.Append(fill5);
}
Borders borders1 = new Borders() { Count = (UInt32Value)1U };
DocumentFormat.OpenXml.Spreadsheet.Border border1 = new DocumentFormat.OpenXml.Spreadsheet.Border();
DocumentFormat.OpenXml.Spreadsheet.LeftBorder leftBorder1 = new DocumentFormat.OpenXml.Spreadsheet.LeftBorder();
DocumentFormat.OpenXml.Spreadsheet.RightBorder rightBorder1 = new DocumentFormat.OpenXml.Spreadsheet.RightBorder();
DocumentFormat.OpenXml.Spreadsheet.TopBorder topBorder1 = new DocumentFormat.OpenXml.Spreadsheet.TopBorder();
DocumentFormat.OpenXml.Spreadsheet.BottomBorder bottomBorder1 = new DocumentFormat.OpenXml.Spreadsheet.BottomBorder();
DocumentFormat.OpenXml.Spreadsheet.DiagonalBorder diagonalBorder1 = new DocumentFormat.OpenXml.Spreadsheet.DiagonalBorder();
border1.Append(leftBorder1);
border1.Append(rightBorder1);
border1.Append(topBorder1);
border1.Append(bottomBorder1);
border1.Append(diagonalBorder1);
borders1.Append(border1);
CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U };
CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U };
cellStyleFormats1.Append(cellFormat1);
CellFormats cellFormats1 = new CellFormats() { Count = (UInt32)(colorCode.Count + 1) };
CellFormat cellFormat0 = new CellFormat()
{
NumberFormatId = (UInt32Value)0U,
FontId = (UInt32Value)0U,
FillId = (UInt32)0,
BorderId = (UInt32Value)0U,
FormatId = (UInt32Value)0U,
ApplyFill = true
};
cellFormats1.Append(cellFormat0);
int colorCodeIndex = 0;
foreach (string color in colorCode)
{
CellFormat cellFormat5 = new CellFormat()
{
NumberFormatId = (UInt32Value)0U,
FontId = (UInt32Value)0U,
FillId = (UInt32)(colorCodeIndex + 2),
BorderId = (UInt32Value)0U,
FormatId = (UInt32Value)0U,
ApplyFill = true
};
cellFormats1.Append(cellFormat5);
colorCodeIndex++;
}
CellStyles cellStyles1 = new CellStyles() { Count = (UInt32Value)1U };
CellStyle cellStyle1 = new CellStyle() { Name = "Normal", FormatId = (UInt32Value)0U, BuiltinId = (UInt32Value)0U };
cellStyles1.Append(cellStyle1);
DifferentialFormats differentialFormats1 = new DifferentialFormats() { Count = (UInt32Value)0U };
TableStyles tableStyles1 = new TableStyles() { Count = (UInt32Value)0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleMedium9" };
StylesheetExtensionList stylesheetExtensionList1 = new StylesheetExtensionList();
StylesheetExtension stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
DocumentFormat.OpenXml.Office2010.Excel.SlicerStyles slicerStyles1 = new DocumentFormat.OpenXml.Office2010.Excel.SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" };
stylesheetExtension1.Append(slicerStyles1);
stylesheetExtensionList1.Append(stylesheetExtension1);
stylesheet1.Append(fonts1);
stylesheet1.Append(fills1);
stylesheet1.Append(borders1);
stylesheet1.Append(cellStyleFormats1);
stylesheet1.Append(cellFormats1);
stylesheet1.Append(cellStyles1);
stylesheet1.Append(differentialFormats1);
stylesheet1.Append(tableStyles1);
stylesheet1.Append(stylesheetExtensionList1);
return stylesheet1;
}

Insert a new worksheet into a spreadsheet document OpenXml

What im trying to do is create multiple worksheets within a work book using datasets the code i have to create a sheet data object from a data set is:
public static SheetData CreateDataSheet(DataSet ds)
{
var xlSheetData = new SheetData();
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
var tbl = ds.Tables[0];
foreach (DataRow row in tbl.Rows)
{
var xlRow = new Row();
foreach (DataColumn col in tbl.Columns)
{
var cellData = row[col];
Cell xlCell = null;
if (cellData != null)
{
xlCell = new Cell(new InlineString(new Text(cellData.ToString())))
{
DataType = CellValues.InlineString
};
}
else
{
xlCell = new Cell(new InlineString(new Text(String.Empty)))
{
DataType = CellValues.InlineString
};
}
xlRow.Append(xlCell);
}
xlSheetData.Append(xlRow);
}
}
return xlSheetData;
}
Then to create the spreadsheet and append the above to the spreadsheet i have:
public static void CreateSpreadsheetWorkbook(string filepath, List<SheetData> sd)
{
var spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
foreach (var x in sd)
{
var newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(x);
var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
uint sheetId = 1;
if (sheets.Elements<Sheet>().Any())
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
var sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(newWorksheetPart), SheetId = sheetId, Name = "mySheet" + sheetId };
sheets.Append(sheet);
workbookpart.Workbook.Save();
}
spreadsheetDocument.Close();
}
This runs with out any errors however when i come to open the document its unable to be opened because it is corrupt.
EDIT - final working version:
public static void CreateSpreadsheetWorkbook(string filepath, List<SheetData> sd)
{
var spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
var workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
foreach (var x in sd)
{
var newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(x);
sheets = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>();
uint sheetId = 1;
if (sheets.Elements<Sheet>().Any())
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
var sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(newWorksheetPart), SheetId = sheetId, Name = "mySheet" + sheetId };
sheets.Append(sheet);
workbookpart.Workbook.Save();
}
spreadsheetDocument.Close();
}
After comparing with some similar code of mine I found these possible problems:
var spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);
//should be
var spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.DocumentType);
And
var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
//should be
var sheets = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>();
after the first time since by the second time you already have a Sheets element.
See this blogpost for more details:
http://blogs.msdn.com/b/brian_jones/archive/2009/02/19/how-to-copy-a-worksheet-within-a-workbook.aspx

Write excel using excel package with formatting

I want to write excel file using excel package from System.Data.DataTable
and need to format some cells in excel file like back ground color.
How can I do that?
Although you may use Interop calls to create an excel file, I prefer solutions without it. According to your given details I found a solution based on OpenXML. No need for Interop but you have to learn the according objectModel from openXML. What you need before you can start:
Download OpenXML SDK and install it from microsoft
Go to openXmlDeveloper.org and learn how to use openXml to create excelFiles
Have a look at several ressources in the web concerning how to access/read/write excelFiles with openXml (such as SO_Question1, social.msdn.microsoft.com_example, Blog1 and SO_Question2)
Afterwards within your project...
Add reference to DocumentFormat.OpenXML library (search your computer, somewhat like C:\Program Files (x86)\Open XML SDK\V2.0\lib\DocumentFormat.OpenXml.dll)
Add reference to WindowBase
And than you are ready to use this piece of code:
// important namespaces
using System.IO.Packaging;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Spreadsheet;
using Excel = DocumentFormat.OpenXml.Office2010.Excel;
static void Main(string[] args)
{
// created a demoTable with id column and five string columns with arbitrary values
DataTable demoTable = CreateDemoTable();
CreateWorkbook(#"c:\ExcelAndStyles.xlsx", demoTable);
}
private static void CreateWorkbook(string fileName, DataTable table)
{
try
{
if (File.Exists(fileName))
File.Delete(fileName);
using (SpreadsheetDocument xl = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook))
{
WorkbookPart wbp = xl.AddWorkbookPart();
WorksheetPart wsp = wbp.AddNewPart<WorksheetPart>();
Workbook wb = new Workbook();
FileVersion fv = new FileVersion();
fv.ApplicationName = "Microsoft Office Excel";
Worksheet ws = new Worksheet();
WorkbookStylesPart wbsp = wbp.AddNewPart<WorkbookStylesPart>();
// add styles to sheet
wbsp.Stylesheet = CreateStylesheet();
wbsp.Stylesheet.Save();
// generate data (row&cells) and add it to workbook
SheetData sd = CreateSheetData(table);
ws.Append(sd);
wsp.Worksheet = ws;
wsp.Worksheet.Save();
Sheets sheets = new Sheets();
Sheet sheet = new Sheet();
sheet.Name = table.TableName;
sheet.SheetId = 1;
sheet.Id = wbp.GetIdOfPart(wsp);
sheets.Append(sheet);
wb.Append(fv);
wb.Append(sheets);
xl.WorkbookPart.Workbook = wb;
xl.WorkbookPart.Workbook.Save();
xl.Close();
}
}
catch (Exception e)
{ // do some errorHandling here }
}
private static Stylesheet CreateStylesheet()
{
// add namespace info
Stylesheet stylesheet1 = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
stylesheet1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
stylesheet1.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
// fonts
Fonts fonts1 = new Fonts() { Count = (UInt32Value)1U, KnownFonts = true };
Font font1 = new Font();
FontSize fontSize1 = new FontSize() { Val = 11D };
Color color1 = new Color() { Theme = (UInt32Value)1U };
FontName fontName1 = new FontName() { Val = "Calibri" };
FontFamilyNumbering fontFamilyNumbering1 = new FontFamilyNumbering() { Val = 2 };
FontScheme fontScheme1 = new FontScheme() { Val = FontSchemeValues.Minor };
font1.Append(fontSize1);
font1.Append(color1);
font1.Append(fontName1);
font1.Append(fontFamilyNumbering1);
font1.Append(fontScheme1);
fonts1.Append(font1);
// fillColor
Fills fills1 = new Fills() { Count = (UInt32Value)5U };
// FillId = 0
Fill fill1 = new Fill();
PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.None };
fill1.Append(patternFill1);
// FillId = 1
Fill fill2 = new Fill();
PatternFill patternFill2 = new PatternFill() { PatternType = PatternValues.Gray125 };
fill2.Append(patternFill2);
// FillId = 2,RED
Fill fill3 = new Fill();
PatternFill patternFill3 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor1 = new ForegroundColor() { Rgb = "FFFF0000" };
BackgroundColor backgroundColor1 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill3.Append(foregroundColor1);
patternFill3.Append(backgroundColor1);
fill3.Append(patternFill3);
// FillId = 3,BLUE
Fill fill4 = new Fill();
PatternFill patternFill4 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor2 = new ForegroundColor() { Rgb = "FF0070C0" };
BackgroundColor backgroundColor2 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill4.Append(foregroundColor2);
patternFill4.Append(backgroundColor2);
fill4.Append(patternFill4);
// FillId = 4,YELLO
Fill fill5 = new Fill();
PatternFill patternFill5 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor3 = new ForegroundColor() { Rgb = "FFFFFF00" };
BackgroundColor backgroundColor3 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill5.Append(foregroundColor3);
patternFill5.Append(backgroundColor3);
fill5.Append(patternFill5);
fills1.Append(fill1); // 0U
fills1.Append(fill2); // 1U
fills1.Append(fill3); // 2U
fills1.Append(fill4); // 3U
fills1.Append(fill5); // 4U
// border styles
Borders borders1 = new Borders() { Count = (UInt32Value)1U };
Border border1 = new Border();
LeftBorder leftBorder1 = new LeftBorder();
RightBorder rightBorder1 = new RightBorder();
TopBorder topBorder1 = new TopBorder();
BottomBorder bottomBorder1 = new BottomBorder();
DiagonalBorder diagonalBorder1 = new DiagonalBorder();
border1.Append(leftBorder1);
border1.Append(rightBorder1);
border1.Append(topBorder1);
border1.Append(bottomBorder1);
border1.Append(diagonalBorder1);
borders1.Append(border1);
// cellFormats
CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U };
CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U };
cellStyleFormats1.Append(cellFormat1);
CellFormats cellFormats1 = new CellFormats() { Count = (UInt32Value)4U };
// see a few lines above - refer to: fills1.Append(XXXX);
// see also ApplyFill = true!!
CellFormat cellFormat2 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U };
CellFormat cellFormat3 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)2U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
CellFormat cellFormat4 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)3U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
CellFormat cellFormat5 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)4U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U, ApplyFill = true };
cellFormats1.Append(cellFormat2); // fillId 0U --- cellFormat Index 0
cellFormats1.Append(cellFormat3); // fillId 2U --- cellFormat Index 1
cellFormats1.Append(cellFormat4); // fillId 3U --- cellFormat Index 2
cellFormats1.Append(cellFormat5); // fillId 4U --- cellFormat Index 3
// cellStyles
CellStyles cellStyles1 = new CellStyles() { Count = (UInt32Value)1U };
CellStyle cellStyle1 = new CellStyle() { Name = "Normal", FormatId = (UInt32Value)0U, BuiltinId = (UInt32Value)0U };
cellStyles1.Append(cellStyle1);
DifferentialFormats differentialFormats1 = new DifferentialFormats() { Count = (UInt32Value)0U };
TableStyles tableStyles1 = new TableStyles() { Count = (UInt32Value)0U, DefaultTableStyle = "TableStyleMedium2", DefaultPivotStyle = "PivotStyleMedium9" };
// extensions
StylesheetExtensionList stylesheetExtensionList1 = new StylesheetExtensionList();
StylesheetExtension stylesheetExtension1 = new StylesheetExtension() { Uri = "{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" };
stylesheetExtension1.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
Excel.SlicerStyles slicerStyles1 = new Excel.SlicerStyles() { DefaultSlicerStyle = "SlicerStyleLight1" };
stylesheetExtension1.Append(slicerStyles1);
stylesheetExtensionList1.Append(stylesheetExtension1);
// add all formats/styles to stylesheet
stylesheet1.Append(fonts1);
stylesheet1.Append(fills1);
stylesheet1.Append(borders1);
stylesheet1.Append(cellStyleFormats1);
stylesheet1.Append(cellFormats1);
stylesheet1.Append(cellStyles1);
stylesheet1.Append(differentialFormats1);
stylesheet1.Append(tableStyles1);
stylesheet1.Append(stylesheetExtensionList1);
return stylesheet1;
}
private static SheetData CreateSheetData(DataTable table)
{
SheetData sheetData = new SheetData();
for (int rowIndex = 0; rowIndex < table.Rows.Count; rowIndex++)
{
DataRow dataRow = table.Rows[rowIndex];
Row row = new Row() { RowIndex = new UInt32Value((uint)(rowIndex + 1)) };
for (int colIndex = 0; colIndex < dataRow.ItemArray.Length; colIndex++)
{
object value = dataRow[colIndex].ToString();
Cell cell = new Cell();
cell.CellReference = ((char)(colIndex + 65)).ToString() + (rowIndex+1).ToString();
// assigned simple red background style
// have a deeper look in CreateStylesheet for details what 1U contains
// for demo purposes may choose 2U and 3U too
cell.StyleIndex = (UInt32Value)1U;
// for demo purposes, treat all values as string
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(table.Rows[rowIndex][colIndex].ToString());
row.Append(cell);
}
sheetData.Append(row);
}
return sheetData;
}
Most of this code has been taken out of several sites listed above! I adopted it and changed it to fit your question. This example code worked for me to create an excelFile containing several rows and columns with differen values and styles.
Hope that helps!

Categories