Adding data to existing excel using open xml sdk 2.5 - excel

I tried to read the existing excel file and copied to another path, and then i tried to insert data to the file i cloned. But I can' insert data. I don't know where I made mistake. But Here I've given my code.
Error occured in the line sheetData.InsertAt<Row>(row,++rowIndex);. Please help me out.
Package spreadsheetPackage = Package.Open(destinationFile, FileMode.Open, FileAccess.ReadWrite);
using (var document = SpreadsheetDocument.Open(spreadsheetPackage))
{
foreach (System.Data.DataTable table in ds.Tables)
{
var workbookPart = document.WorkbookPart;
var workbook = workbookPart.Workbook;
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault();
Worksheet ws = ((WorksheetPart)(workbookPart.GetPartById(sheet.Id))).Worksheet;
SheetData sheetData = ws.GetFirstChild<SheetData>();
//Sheet sheet = sheets.FirstOrDefault();
if(sheet==null)
throw new Exception("No sheed found in the template file. Please add the sheet");
int rowIndex = 10, colIndex = 0;
bool flag = false;
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
var rows = worksheetPart.Worksheet.Descendants<Row>();
List<String> columns = new List<string>();
foreach (System.Data.DataColumn column in table.Columns)
{
columns.Add(column.ColumnName);
}
foreach (System.Data.DataRow dsrow in table.Rows)
{
Row row = new Row();
foreach (String col in columns)
{
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString());
row.AppendChild<Cell>(cell);
}
sheetData.InsertAt<Row>(row,++rowIndex);
}
}

Before you append Row, you should mentioned the row index to the instance...
row.RowIndex = (UInt32)rowIndex++;

Related

programmatically print out cell and comments contents from spreadsheet

I have a spreadsheet with worksheets (originally in Google Sheets, but I can export to .xlsx or .ods) and I would like to programmatically print out the cell values of the first line along with the comments in each cell. E.g. see screenshot below of worksheet (https://docs.google.com/spreadsheets/d/1DGsrEKrxfQm8sRzfLyqu4z6Hx8eDdkVDiYlN3Rwve6A/edit?usp=sharing):
There are 3 cells in row1 each with a comment in them.
I would like to programmatically print out the contents of this worksheet so that they look something like:
Cell:"field1",Comment:"key=foobar"
Cell:"field2",Comment:"key=bar"
Cell:"field3",Comment:"key=foobar"
Any ideas?
google-spreadsheets
function getNotes_(fileId, sheetName, rangeA1)
{
var data = [];
var file = SpreadsheetApp.openById(fileId);
var sheet = file.getSheetByName(sheetName);
var range = sheet.getRange(rangeA1);
var values = range.getValues();
var notes = range.getNotes();
var getResult_ = function(value, i) { data.push( 'Cell:"' + value + '",Comment:"' + rowNotes[i] +'"') };
var rowNotes = [];
for (var i = 0, l = values.length; i < l; i++)
{
rowNotes = notes[i];
values[i].forEach(getResult_);
}
return data;
}

How to read cell data of excel file using openxml

I am reading the .xlsx file using DocumentFormat.openxml nuget pkg. I am trying to read the date cell[G2] and data from [b5] to [m5]
static void Main(string[] args)
{
string sFileTypeError = string.Empty;
string myFilePath = #"C:\Landing\file.xlsx";
//string ext = Path.GetExtension(myFilePath);
var fileName = Path.GetFileName(myFilePath);
var fileExtension = Path.GetExtension(fileName);
if ((fileExtension != ".xlsx") && (fileExtension != ".xls"))
sFileTypeError = "Invalid file. \n\nPlease browse a correct Excel file to upload.";
else
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(myFilePath, false))
{
IEnumerable<Sheet> sheets = doc.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>().Elements<Sheet>();
WorksheetPart worksheetPart = (WorksheetPart)doc.WorkbookPart.GetPartById(sheets.First().Id.Value);
IEnumerable<Row> rows = worksheetPart.Worksheet.GetFirstChild<SheetData>().Descendants<Row>();
}
}
}
Please let me know how can read this. Thanks
I you want to go row by row and then cell by cell you can do this :
foreach (Row actualRow in rows)
{
IEnumerable<Cell> cells = actualRow.Descendants<Cell>();
foreach (Cell actualCell in cells)
{
// It gets the good value if it's not in the shared string table
string value = actualCell.CellValue.Text;
}
}

NPOI set Explicit Column Type Not working properly

I'm using NPOI Excel Library to generate a Excel file, in that Excel file i'm explicitly define column type for Columns like Date,String etc.
Im using the following code to achive this.
var row = sheet.CreateRow(currentNPOIRowIndex++);
for (var colIndex = 0; colIndex < exportData.Columns.Count; colIndex++)
{
ICell cell = null;
cell = row.CreateCell(colIndex);
if (exportData.Columns[colIndex].DataType == typeof(DateTime))
{
if (exportData.Rows[rowIndex][colIndex].ToString() != "")
{
cell.SetCellValue((DateTime)exportData.Rows[rowIndex][colIndex]);
cell.CellStyle = (NPOI.HSSF.UserModel.HSSFCellStyle)book.CreateCellStyle();
cell.CellStyle.DataFormat = book.CreateDataFormat().GetFormat("yyyyMMdd HH:mm:ss");
cell = null;
}
else
cell.SetCellValue(exportData.Rows[rowIndex][colIndex].ToString());
}
else
cell.SetCellValue(exportData.Rows[rowIndex][colIndex].ToString());
}
}
The above code works fine for 42 rows i.e. it correctly set the Column Type,but after 42 rows Column Type doesn't apply.
Any help will be highly appreciated.
you'll required to set default column style if you want to set column format for all cells of that column. Please see the below example from xssf format. Syntax may differ for your hssf format but it will give you idea what you are missing.
I am providing you from my working code. I am using NPOI version 2.2.1.0.
can you comment line //cell = null;
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet("Template");
XSSFFont defaultFont = (XSSFFont)workbook.CreateFont();
defaultFont.FontHeightInPoints = (short)10;
XSSFCellStyle headerStyle = (XSSFCellStyle)workbook.CreateCellStyle();
headerStyle.WrapText = true;
XSSFCellStyle defaultStyle = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat defaultDataFormat = (XSSFDataFormat)workbook.CreateDataFormat();
defaultStyle.SetDataFormat(defaultDataFormat.GetFormat("000-000-0000"));
defaultStyle.FillBackgroundColor = IndexedColors.LightYellow.Index;
defaultStyle.FillForegroundColor = IndexedColors.LightTurquoise.Index;
defaultStyle.SetFont(defaultFont);
var row = sheet.CreateRow(0);
for (int headerCount = 0; headerCount < headers.Count(); headerCount++)
{
row.CreateCell(headerCount).SetCellValue(headers[headerCount]);
row.Cells[headerCount].CellStyle = headerStyle;
sheet.SetDefaultColumnStyle(headerCount, defaultStyle);
}

Named Ranges in Excel OpenXML

I am trying to create named ranges in Excel with OpenXML. I am able to add a DefinedName in the DefinedNames collection, but that does not seem to do anything. I noticed a place in the ExtendedFileProperties where the names of ranges are being saved, a structure called "TitlesOfParts". I have tried adding an entry in there but that causes excel to throw an error and the named range is not created. Here is the code I am using:
public void AddNamedRange(string pNamedRangeRef, string pNamedRangeName)
{
DefinedName _definedName = new DefinedName() { Name = pNamedRangeName, Text = pNamedRangeRef };
_workbook.Descendants<DocumentFormat.OpenXml.Spreadsheet.DefinedNames>().First().Append(_definedName);
DocumentFormat.OpenXml.VariantTypes.VTLPSTR _t = new DocumentFormat.OpenXml.VariantTypes.VTLPSTR() { Text = pNamedRangeName };
_spreadsheet.ExtendedFilePropertiesPart.Properties.TitlesOfParts.VTVector.Append(_t);
_spreadsheet.ExtendedFilePropertiesPart.Properties.TitlesOfParts.VTVector.Size++;
}
Using the Open XML SDK 2.0 Productivity Tool for Microsoft Office, to define a global/workbook-wide named range is pretty easy:
DefinedNames definedNamesCol = new DefinedNames(); //Create the collection
DefinedName definedName = new DefinedName()
{ Name = "test", Text="Sheet1!$B$2:$B$4" }; // Create a new range
definedNamesCol.Append(definedName); // Add it to the collection
workbook.Append(definedNamesCol); // Add collection to the workbook
The below code did the trick for me. After this I was able to see the name ranges in excel also.
var wbPart = document.WorkbookPart;
Workbook workbook = wbPart.Workbook;
DefinedName definedName1 = new DefinedName { Name = "ColumnRange",Text = "Sheet1!$A$1:$I$1"};
DefinedName definedName2 = new DefinedName { Name = "RowRange", Text = "Sheet1!$A$1:$A$15"};
if (workbook.DefinedNames == null)
{
DefinedNames definedNames1 = new DefinedNames();
definedNames1.Append(definedName1);
definedNames1.Append(definedName2);
workbook.DefinedNames = definedNames1;
}
'vb.net
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Dim WB As SpreadsheetDocument = SpreadsheetDocument.Create("C:\NewFile.xmlx", SpreadsheetDocumentType.Workbook)
Dim WBP As WorkbookPart = WB.AddWorkbookPart
Dim dn As DefinedName = New DefinedName()
dn.Name = "test"
dn.Text = "XFW_PLP_CalcPlan!A5:$I$1"
Dim dns As DefinedNames = New DefinedNames()
dns.Append(dn)
WBP.Workbook.Append(dns)

how create a excel file with multiple sheets using ExcelPackage

This source code:
using (ExcelPackage xlPackage = new ExcelPackage(newFile, template))
{
ExcelWorksheet worksheet = null;
foreach (DataTable dt in dsExcel.Tables)
{
worksheet = xlPackage.Workbook.Worksheets.Add(dt.TableName);
worksheet = xlPackage.Workbook.Worksheets[dt.TableName];
ExcelCell cell;
const int startRow = 9;
int row = startRow;
int col = 1;
foreach (DataRow dr in dt.Rows)
{
foreach (DataColumn dc in dt.Columns)
{
worksheet.Cell(row, col).Value = dr[dc].ToString();
col++;
}
col = 1;
row++;
}
}
xlPackage.Save();
}
I am getting error at xlpackage.save i.e. object reference not set to an instance.
How to generate an excel file with multiplesheets using an excel template?
Looks like this is a bug, documented here. Unfortunately, it looks like the fix is to edit the source code of ExcelPackage itself.

Resources