Having issue with writing text to specific Excel Cell using OpenXml - c#

What I want to achieve is illustrated below:
The result and issue I've been having are illustrated below:
This is the result file my code has generated and there supposed to have expected content.
Window prompt after the 'Yes' button has clicked.
My running code is given below:
Main method:
public static void Main(string[] args)
{
WriteExcelService writeExcelService = new WriteExcelService();
Dictionary<string, List<string>> contentList = new Dictionary<string, List<string>>
{
{ "en-US",new List<string> (new string[] { "Dummy text 01","Dummy text 02"}) },
{ "es-ES",new List<string> (new string[] { "Texto ficticio 01", "Texto ficticio 02"}) }
};
string inputFile = #"C:\{username}\Desktop\Valentines_Day.xlsx";
string sheetName = "Copy";
writeExcelService.WriteValueToCell(inputFile, sheetName, contentList);
}
WriteValueToCell method:
char columnName = 'I';
uint rowNumber = 1;
foreach (var keys in contentList.Keys)
{
foreach (var value in contentList.Where(v => v.Key == keys).SelectMany(v => v.Value))
{
string cellAddress = String.Concat(columnName, rowNumber);
this.Write(filepath, sheetName, value, cellAddress, rowNumber);
int tempColumn = (int)columnName;
columnName = (char)++tempColumn;
}
columnName = 'I';
++rowNumber;
}
Write method:
private void Write(string filepath, string sheetName, string value, string cellAddress,uint rowNumber)
{
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
//writeExcelService.WriteValueToCell(outputFilePath, sheetName, cellAddress, value.Value);
// 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 = sheetName };
sheets.Append(sheet);
// Get the sheetData cell table.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// Add a row to the cell table.
Row row;
row = new Row() { RowIndex = rowNumber };
sheetData.Append(row);
// In the new row, find the column location to insert a cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, cellAddress, true) > 0)
{
refCell = cell;
break;
}
}
// Add the cell to the cell table.
Cell newCell = new Cell() { CellReference = cellAddress };
row.InsertBefore(newCell, refCell);
// Set the cell value to be a numeric value.
newCell.CellValue = new CellValue(value);
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
}
}
My problem is:
My code executes but once the result file is opened, It prompts window as I posted above, and the file is empty.If I debug the code to insert list of contents one by one, it can be written correctly to Cells I2 or J2. Since my code creates SpreadsheetDocument for each list content, therefore I have changed the SpreadsheetDocument creation approach in the code below:
using (SpreadsheetDocument spreadsheetDocument = File.Exists(filePath) ?
SpreadsheetDocument.Open(filepath, true) :
SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
}
But I am getting exception
Only one instance of the type is allowed for this parent.
Anyone can help me on this?
Appreciate it in advance.

Strings in excel are saved under a sharedStringTable. When inserting a string it is important to add the string or reference the string from the sharedStringTable. Also, you need to provide the correct DataType for a cell. In your code, you are inserting all values as a number:
// Set the cell value to be a numeric value.
newCell.CellValue = new CellValue(value);
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
To insert a string I would recommend using the following method after you have created a new cell:
private SpreadsheetDocument _spreadSheet;
private WorksheetPart _worksheetPart;
..
..
private void UpdateCell(Cell cell, DataTypes type, string text)
{
if (type == DataTypes.String)
{
cell.DataType = CellValues.SharedString;
if (!_spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Any())
{
_spreadSheet.WorkbookPart.AddNewPart<SharedStringTablePart>();
}
var sharedStringTablePart = _spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
if (sharedStringTablePart.SharedStringTable == null)
{
sharedStringTablePart.SharedStringTable = new SharedStringTable();
}
//Iterate through shared string table to check if the value is already present.
foreach (SharedStringItem ssItem in sharedStringTablePart.SharedStringTable.Elements<SharedStringItem>())
{
if (ssItem.InnerText == text)
{
cell.CellValue = new CellValue(ssItem.ElementsBefore().Count().ToString());
return;
}
}
// The text does not exist in the part. Create the SharedStringItem.
var item = sharedStringTablePart.SharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
cell.CellValue = new CellValue(item.ElementsBefore().Count().ToString());
}
else if (type == DataTypes.Number)
{
cell.CellValue = new CellValue(text);
cell.DataType = CellValues.Number;
}
else if (type == DataTypes.DateTime)
{
cell.DataType = CellValues.Number;
cell.StyleIndex = Convert.ToUInt32(_dateStyleIndex);
DateTime dateTime = DateTime.Parse(text);
double oaValue = dateTime.ToOADate();
cell.CellValue = new CellValue(oaValue.ToString(CultureInfo.InvariantCulture));
}
_worksheetPart.Worksheet.Save();
}

I have figured out the solution myself. I have passed the list of string contents and write them all to corresponding Cells then closed the SpreadSheetDocument. In this way SpreadSheetDocument can be created once. Working code is below:
public void WriteValueToCell(string filepath, string sheetName, Dictionary<string, List<string>> contentList)
{
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook, true))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
//Add a WorkbookStylesPart to the workbookpart
WorkbookStylesPart stylesPart = workbookpart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = new Stylesheet();
// 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 = sheetName };
sheets.Append(sheet);
// Get the sheetData cell table.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
char columnName = 'I';
uint rowNumber = 1;
foreach (var keys in contentList.Keys)
{
foreach (var value in contentList.Where(v => v.Key == keys).SelectMany(v => v.Value))
{
string cellAddress = String.Concat(columnName, rowNumber);
// Add a row to the cell table.
Row row;
row = new Row() { RowIndex = rowNumber };
sheetData.Append(row);
// In the new row, find the column location to insert a cell.
Cell refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, cellAddress, true) > 0)
{
refCell = cell;
break;
}
}
// Add the cell to the cell table.
Cell newCell = new Cell() { CellReference = cellAddress };
row.InsertBefore(newCell, refCell);
// Set the cell value to be a numeric value.
newCell.CellValue = new CellValue(value);
newCell.DataType = new EnumValue<CellValues>(CellValues.String);
int tempColumn = (int)columnName;
columnName = (char)++tempColumn;
}
columnName = 'I';
++rowNumber;
}
}
}
Main method:
public static void Main(string[] args)
{
WriteExcelService writeExcelService = new WriteExcelService();
Dictionary<string, List<string>> contentList = new Dictionary<string, List<string>>
{
{ "en-US",new List<string> (new string[] { "Dummy text 01","Dummy text 02"}) },
{ "es-ES",new List<string> (new string[] { "Texto ficticio 01", "Texto ficticio 02"}) }
};
string inputFile = #"C:\{username}\Desktop\Valentines_Day.xlsx";
string sheetName = "Copy";
writeExcelService.WriteValueToCell(inputFile, sheetName, contentList);
}

Related

C# OpenXML Changing Column Background

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;
}

How can I fit all columns on one page in a spreadsheet?

I have exported the report to Excel and it works fine, but when I print the file the width of the spreadsheet doesn't fit all column into one page. For this to happen I have to change the Page Layout, and set the scaling to fit 1 on width and 43 tall. How can I get this from code?
using (var workbook = SpreadsheetDocument.Create(Savepath, SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook();
workbook.WorkbookPart.Workbook.Sheets = new Sheets();
//declare our MergeCells here
MergeCells mergeCells = null;
foreach (DataRow dsrow in table.Rows)
{
int innerColIndex = 0;
rowIndex++;
Row newRow = new Row();
foreach (String col in columns)
{
Stylesheet stylesheet1 = new Stylesheet();
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dsrow[col].ToString());
cell.CellReference = excelColumnNames[innerColIndex] + rowIndex.ToString();
if (table.TableName == "Work Order Report")
{
string cellNameWorkOrder = dsrow[col].ToString();
if (cellNameWorkOrder == "POSTER: 10% MUST HAVE APPROACH AND CLOSE-UP SHOTS - PHOTO OF EACH CREATIVE" || cellNameWorkOrder == "BULLETINS: 100% CLOSE-UP AND APPROACH OF EACH UNIT")
{
if (mergeCells == null)
mergeCells = new MergeCells();
var cellAddress = cell.CellReference;
var cellAddressTwo = "I" + rowIndex.ToString();
mergeCells.Append(new MergeCell() { Reference = new StringValue(cellAddress + ":" + cellAddressTwo) });
}
}
newRow.AppendChild(cell);
innerColIndex++;
}
sheetData.AppendChild(newRow);
}
//add the mergeCells to the worksheet if we have any
if (mergeCells != null)
sheetPart.Worksheet.InsertAfter(mergeCells, sheetPart.Worksheet.Elements<SheetData>().First());
}
workbook.WorkbookPart.Workbook.Save();
}
The excel report looks like https://www.screencast.com/t/CCMR96Mw7u when I print now its like https://www.screencast.com/t/MkTpDc98RD0l ,https://www.screencast.com/t/MRyzpEiFICM the expected result is https://www.screencast.com/t/ztgvm6mISSwp
In order to achieve this you need to do two things. Firstly, you need to add a PageSetupProperties instance to a SheetProperties instance which in turn should get added to your Worksheet. The PageSetupProperties has a FitToPage property which is the part that sets the radio button in Excel to "Fit to".
Next, you need to use the PageSetup class in order to set the width and height required. This is done via the FitToWidth and FitToHeight properties. The PageSetup also needs to be added to the Worksheet.
Note that the order of the elements is important, you can see the correct order in the ECMA spec.
The following is a self contained example that adds one cell and then sets the properties the way that you need them:
using (SpreadsheetDocument myDoc = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
WorkbookPart workbookpart = myDoc.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
SheetData sheetData = new SheetData();
//add a row
Row row = new Row();
row.RowIndex = 1;
//create a cell
Cell cell = new Cell();
cell.CellReference = "A1";
CellValue cellValue = new CellValue();
cellValue.Text = "123";
cell.Append(cellValue);
row.AppendChild(cell);
sheetData.AppendChild(row);
// Add a WorkbookPart to the document.
worksheetPart.Worksheet = new Worksheet(sheetData);
//this sets the "Fit to" radio in Excel.
//note this must come before the SheetData
SheetProperties sheetProperties = new SheetProperties();
PageSetupProperties pageSetupProperties = new PageSetupProperties() { FitToPage = true };
sheetProperties.Append(pageSetupProperties);
worksheetPart.Worksheet.InsertBefore(sheetProperties, sheetData);
// this changes the fit to width and height
PageSetup pageSetup = new PageSetup() { FitToWidth = 1, FitToHeight = 43 };
worksheetPart.Worksheet.AppendChild(pageSetup);
//append the sheets / sheet
Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
sheets.AppendChild(new Sheet()
{
Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
SheetId = 1,
Name = "Sheet1"
});
}

Excel Open error: “found unreadable content” when creating Excel

I am getting error 'Excel found unreadable content in APPL_1.xlsx.'
What is wrong in my code?.
Record contain around 2 lacks data. I am trying to fetch it from datatable to excel.
I am using OpenXMLSpreedsheetDocument to fetch data from datatable to excel
FileInfo FileLoc = new FileInfo(FilePath);
if (FileLoc.Exists)
{
FileLoc.Delete();
FileLoc = new FileInfo(FilePath);
}
SpreadsheetDocument spreadSheet = SpreadsheetDocument.
Create(FilePath, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
WorkbookPart workbookpart = spreadSheet.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 Bold();
CellFormat cf = new CellFormat();
// Add Sheets to the Workbook.
Sheets sheets;
sheets = spreadSheet.WorkbookPart.Workbook.
AppendChild<Sheets>(new Sheets());
// Append a new worksheet and associate it with the workbook.
var sheet = new Sheet()
{
Id = spreadSheet.WorkbookPart.
GetIdOfPart(worksheetPart),
SheetId = 0,
Name = "Sheet" + 0
};
sheets.Append(sheet);
//Add Header Row.
var headerRow = new Row();
foreach (DataColumn column in dt.Columns)
{
var cell = new Cell
{
DataType = CellValues.String,
CellValue = new CellValue(column.ColumnName)
};
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow row in dt.Rows)
{
var newRow = new Row();
foreach (DataColumn col in dt.Columns)
{
Cell c = new Cell();
c.DataType = new EnumValue<CellValues>(CellValues.String);
c.CellValue = new CellValue(row[col].ToString());
newRow.Append(c);
}
sheetData.AppendChild(newRow);
}
workbookpart.Workbook.Save();
ProcessStartInfo startInfo = new ProcessStartInfo(FilePath);
Process.Start(startInfo);
Any suggestions is much appreciated..!!
Here is my implementation of OpenXML. For simplicity, I have excluded the cell styling code.
This creates an excel file with two rows and 3 columns. You can modify this to suit your needs.
Main method:
static void Main(string[] args)
{
var dtToXl = new DtToExcel();
var dt = new DataTable();
dt.Columns.Add("Col1");
dt.Columns.Add("Col2");
dt.Columns.Add("Col3");
dt.Rows.Add("R1C1", "R1C2", "R1C3");
dt.Rows.Add("R2C1", "R2C2", "R2C3");
dtToXl.GetExcel(dt);
if(Debugger.IsAttached)
{
Console.ReadLine();
}
}
GetExcel method:
public void GetExcel(DataTable dt)
{
using (var document = SpreadsheetDocument.Create("C:\\Desktop\\Excel1.xlsx", SpreadsheetDocumentType.Workbook))
{
var workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
var sheets = workbookPart.Workbook.AppendChild(new Sheets());
AddWorksheet(dt, 1, ref sheets, ref workbookPart);
}
}
AddWorksheet method:
private void AddWorksheet(DataTable dt, int sheetCount, ref Sheets sheets, ref WorkbookPart workbookPart)
{
var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
var sheetName = $"Sheet{sheetCount}";
worksheetPart.Worksheet = new Worksheet();
//Create header rows
#region Excel Headers
Row row = new Row
{
RowIndex = 1
};
row.AppendChild(AddCellWithValue("Column 1", CellValues.InlineString));
row.AppendChild(AddCellWithValue("Column 2", CellValues.InlineString));
row.AppendChild(AddCellWithValue("Column 3", CellValues.InlineString));
sheetData.AppendChild(row);
#endregion
//Create data rows
#region Excel data rows
var rowIndex = (UInt32)2;
foreach (DataRow dtRow in dt.Rows)
{
row = new Row
{
RowIndex = rowIndex++
};
row.AppendChild(AddCellWithValue(dtRow[0].ToString(), CellValues.InlineString));
row.AppendChild(AddCellWithValue(dtRow[1].ToString(), CellValues.InlineString));
row.AppendChild(AddCellWithValue(dtRow[2].ToString(), CellValues.InlineString));
sheetData.AppendChild(row);
}
#endregion
var columns = new Columns();
columns.Append(new Column() { Min = 1, Max = 1, Width = 20, CustomWidth = true });
columns.Append(new Column() { Min = 2, Max = 2, Width = 20, CustomWidth = true });
columns.Append(new Column() { Min = 3, Max = 3, Width = 20, CustomWidth = true });
worksheetPart.Worksheet.Append(columns);
worksheetPart.Worksheet.Append(sheetData); //This line should be anywhere below .Append(columns)
var sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = (UInt32)sheetCount, Name = sheetName };
sheets.Append(sheet);
}
AddCellWithValue method
private Cell AddCellWithValue(string value, CellValues type)
{
var cell = new Cell
{
DataType = type
};
if (type == CellValues.InlineString)
{
var inlineString = new InlineString();
var t = new Text
{
Text = value
};
inlineString.AppendChild(t);
cell.AppendChild(inlineString);
}
else
{
cell.CellValue = new CellValue(value);
}
return cell;
}
I have used SpreadsheetLight.
Here is my code.
using SpreadsheetLight;
SLDocument sl = new SLDocument();
int iStartRowIndex = 1;
int iStartColumnIndex = 1;
sl.ImportDataTable(iStartRowIndex, iStartColumnIndex, dt, true);
// + 1 because the header row is included
// - 1 because it's a counting thing, because the start row is counted.
int iEndRowIndex = iStartRowIndex + dt.Rows.Count + 1 - 1;
// - 1 because it's a counting thing, because the start column is counted.
int iEndColumnIndex = iStartColumnIndex + dt.Columns.Count - 1;
SLTable table = sl.CreateTable(iStartRowIndex, iStartColumnIndex, iEndRowIndex, iEndColumnIndex);
table.SetTableStyle(SLTableStyleTypeValues.Medium17);
table.HasTotalRow = true;
table.SetTotalRowFunction(5, SLTotalsRowFunctionValues.Sum);
sl.InsertTable(table);
sl.SaveAs(FilePath);
sl.Dispose();
ProcessStartInfo startInfo = new ProcessStartInfo(FilePath);
Process.Start(startInfo);

How can we insert the next row of the excel sheet if the current excel sheet having the records?

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();
}
}

Download OpenXML generated

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();
}

Categories

Resources