Read excel values to key value pair using open xml - c#

I have an array of excel cell addresses, I just need to read these cell values to a dictionary, ie, I need to use open xml to do this. Any help?
When I'm reading I'm getting only numeric values and some numbers are coming for string type cells. Or any specific way to read multiple cells from excel using openxml?
public static Dictionary<string, string> GetCellValue(string filePath, string sheetName)
{
string[] adderssNames = { "H29", "H30", "H31", "H32", "H33", "H36", "H37", "H38", "H40", "H41", "H42", "H43", "H47",
"H48", "H49", "H50", "H51", "H52", "H57", "H58", "H61", "H62", "H65", "H66", "H69", "H70",
"I29", "I30", "I31", "I32", "I33", "I36", "I37", "I38", "I40", "I41", "I42", "I43", "I47",
"I48", "I49", "I50", "I51", "I52", "I57", "I58", "I61", "I62", "I65", "I66", "I69", "I70",
"J29", "J30", "J31", "J32", "J33", "J36", "J37", "J38", "J40", "J41", "J42", "J43", "J47",
"J48", "J49", "J50", "J51", "J52", "J57", "J58", "J61", "J62", "J65", "J66", "J69", "J70",
"K29", "K30", "K31", "K32", "K33", "K36", "K37", "K38", "K40", "K41", "K42", "K43", "K47",
"K48", "K49", "K50", "K51", "K52", "K57", "K58", "K61", "K62", "K65", "K66", "K69", "K70",
"L29", "L30", "L31", "L32", "L33", "L36", "L37", "L38", "L40", "L41", "L42", "L43", "L47",
"L48", "L49", "L50", "L51", "L52", "L57", "L58", "L61", "L62", "L65", "L66", "L69", "L70",
};
Dictionary<string, string> cellValues = new Dictionary<string, string>();
string value = null;
using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false))
{
WorkbookPart wbPart = document.WorkbookPart;
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
throw new ArgumentException("Invalid sheet name");
}
WorksheetPart wsPart =
(WorksheetPart)(wbPart.GetPartById(theSheet.Id));
for (int i = 0; i < adderssNames.Length; i++)
{
Cell theCell = wsPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == adderssNames[i]).FirstOrDefault();
if (theCell != null)
{
value = theCell.CellValue == null ? "" : theCell.CellValue.Text;
cellValues.Add(adderssNames[i], value);
if (theCell.DataType != null)
{
switch (theCell.DataType.Value)
{
case CellValues.SharedString:
var stringTable =
wbPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
if (stringTable != null)
{
value =
stringTable.SharedStringTable
.ElementAt(int.Parse(value)).InnerText;
}
break;
case CellValues.Boolean:
switch (value)
{
case "0":
cellValues[adderssNames[i]] = "FALSE";
break;
default:
cellValues[adderssNames[i]] = "TRUE";
break;
}
break;
}
}
}
}
}
return cellValues;
}
Thanks
Ragesh

Related

Converting Excel to CSV with C# getting extra , on each row

Am converting an Excel file to a CSV in a Azure WebJob to keep the file in blob storage during the process using C# but am getting an extra comma after each row in my csv file.
Example:
1,Test,Doe,
2,Test,John,
Here is my code for producing the csv:
public static class ExcelToCSVConvertor
{
public static List<BlobInput> Convert(List<BlobOutput> inputs)
{
var dataForBlobInput = new List<BlobInput>();
try
{
foreach (BlobOutput item in inputs)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(item.BlobContent, false))
{
foreach (Sheet _Sheet in document.WorkbookPart.Workbook.Descendants<Sheet>())
{
WorksheetPart _WorksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(_Sheet.Id);
Worksheet _Worksheet = _WorksheetPart.Worksheet;
SharedStringTablePart _SharedStringTablePart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringItem[] _SharedStringItem = _SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ToArray();
StringBuilder stringBuilder = new StringBuilder();
foreach (var row in _Worksheet.Descendants<Row>())
{
foreach (Cell _Cell in row)
{
string Value = string.Empty;
if (_Cell.CellValue != null)
{
if (_Cell.DataType != null && _Cell.DataType.Value == CellValues.SharedString)
Value = _SharedStringItem[int.Parse(_Cell.CellValue.Text)].InnerText;
else
Value = _Cell.CellValue.Text;
}
stringBuilder.Append(string.Format("{0},", Value.Trim()));
}
stringBuilder.Append("\n");
}
byte[] data = Encoding.UTF8.GetBytes(stringBuilder.ToString().Trim());
string fileNameWithoutExtn = item.BlobName.ToString().Substring(0, item.BlobName.ToString().IndexOf("."));
string newFilename = $"{fileNameWithoutExtn}_{_Sheet.Name}.csv";
dataForBlobInput.Add(new BlobInput { BlobName = newFilename, BlobContent = data });
}
}
}
}
catch (Exception Ex)
{
throw Ex;
}
return dataForBlobInput;
}
}
This line is adding comma after EVERY single value
stringBuilder.Append(string.Format("{0},", Value.Trim()));
1,
Test,
Doe,
2,
Test,
John,
You need to exclude the comma on last value in row (last iteration).
On last iteration foreach (Cell _Cell in row) stringBuilder.Append should be
stringBuilder.Append(string.Format("{0}", Value.Trim()));

Import *.xlsx data via ExcelDataReader with 0 number of records affected

I use ExcelDataReader and ExcelDataReader.DataSet libraries to read over 1700 rows from and xlsx-file. Eventually, there are no records read. However if we restrict number of rows in a dile down to 9 - all the rows data are read correctly. Here is code:
private IEnumerable<T> ParseImportSourceFile<T>(string fileName, byte[] file) where T : CsvClassMap
{
IEnumerable<T> records = null;
var extensionEnd = Path.GetExtension(fileName).ToLower();
switch (Path.GetExtension(fileName).ToLower())
{
case ".csv":
break;
case ".xls":
case ".xlsx":
case ".ods":
records = new List<T>();
var memoryStream = new MemoryStream(file);
var streamReader = new StreamReader(memoryStream);
var reader = ExcelReaderFactory.CreateReader(streamReader.BaseStream);
if (extensionEnd == ".xlsx")
{
reader = ExcelReaderFactory.CreateOpenXmlReader(streamReader.BaseStream);
//reader.
}
//reader.AsDataSet().
try
{
var result = reader.AsDataSet(new ExcelDataSetConfiguration()
{
UseColumnDataType = true,
ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
{
EmptyColumnNamePrefix = "Column",
UseHeaderRow = true,
}
});
if (result.Tables.Count > 0)
{
var tbl = result.Tables[0];
//grab column names into array
var columns = new DataColumn[tbl.Columns.Count];
tbl.Columns.CopyTo(columns, 0);
//grab properties of T class
var tType = typeof(T);
var properties = tType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < tbl.Rows.Count; i++)
{
//one row one record... create an instance for each row
var row = tbl.Rows[i];
var record = Activator.CreateInstance<T>();
//read all columns and try set valid property
foreach (var col in columns)
{
var prop = properties.FirstOrDefault(x => x.Name == col.ColumnName ||
(x.GetCustomAttribute<DisplayAttribute>() != null && x.GetCustomAttribute<DisplayAttribute>().Name == col.ColumnName));
if (prop != null && prop.CanWrite)
{
//
var sourceValue = row[col.ColumnName];
if(!(sourceValue is DBNull))
prop.SetValue(record, Parse(prop.PropertyType, sourceValue.ToString()));
}
}
((IList<T>)records).Add(record);
}
}
}
finally
{
if (reader != null) reader.Dispose();
if (streamReader != null) streamReader.Dispose();
if (memoryStream != null) memoryStream.Dispose();
}
break;
default:
throw new ImportException("Template is not valid.");
}
return records;
}
I use CreateOpenXmlReader method for xlsx file as it was suggessted on
stackoverflow.
tbl.Rows.Count is zero - from more than 1700 rows in xlsx file. Please help

C# OpenXML copy and paste excel sheet to new workbook

I have multiple workbooks with the same sheet name. I want to copy all the individual sheets to one workbook. The code I have so far copies the text but it doesn't keep formatting , so I lose the colors, borders etc. Can someone suggest any improvements to include styles also and keep formatting? Thanks
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
namespace openxmlExcelTryout
{
class OpenXMLCopySheet
{
private static int tableId;
public static void CopySheet(string filename, string sheetName, string clonedSheetName, string destFileName)
{
//Open workbook
using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(filename, true))
{
WorkbookPart workbookPart = mySpreadsheet.WorkbookPart;
//Get the source sheet to be copied
WorksheetPart sourceSheetPart = GetWorkSheetPart(workbookPart, sheetName);
SharedStringTablePart sharedStringTable = workbookPart.SharedStringTablePart;
//Take advantage of AddPart for deep cloning
using (SpreadsheetDocument newXLFile = SpreadsheetDocument.Create(destFileName, SpreadsheetDocumentType.Workbook))
{
WorkbookPart newWorkbookPart = newXLFile.AddWorkbookPart();
SharedStringTablePart newSharedStringTable = newWorkbookPart.AddPart<SharedStringTablePart>(sharedStringTable);
WorksheetPart newWorksheetPart = newWorkbookPart.AddPart<WorksheetPart>(sourceSheetPart);
//Table definition parts are somewhat special and need unique ids...so let's make an id based on count
int numTableDefParts = sourceSheetPart.GetPartsCountOfType<TableDefinitionPart>();
tableId = numTableDefParts;
//Clean up table definition parts (tables need unique ids)
if (numTableDefParts != 0)
FixupTableParts(newWorksheetPart, numTableDefParts);
//There should only be one sheet that has focus
CleanView(newWorksheetPart);
var fileVersion = new FileVersion { ApplicationName = "Microsoft Office Excel" };
//Worksheet ws = newWorksheetPart.Worksheet;
Workbook wb = new Workbook();
wb.Append(fileVersion);
//Add new sheet to main workbook part
Sheets sheets = null;
//int sheetCount = wb.Sheets.Count();
if (wb.Sheets != null)
{ sheets = wb.GetFirstChild<Sheets>(); }
else
{ sheets = new Sheets(); }
Sheet copiedSheet = new Sheet
{
Name = clonedSheetName,
Id = newWorkbookPart.GetIdOfPart(newWorksheetPart)
};
if (wb.Sheets != null)
{ copiedSheet.SheetId = (uint)sheets.ChildElements.Count + 1; }
else { copiedSheet.SheetId = 1; }
sheets.Append(copiedSheet);
newWorksheetPart.Worksheet.Save();
wb.Append(sheets);
//Save Changes
newWorkbookPart.Workbook = wb;
wb.Save();
newXLFile.Close();
}
}
}
static void CleanView(WorksheetPart worksheetPart)
{
//There can only be one sheet that has focus
SheetViews views = worksheetPart.Worksheet.GetFirstChild<SheetViews>();
if (views != null)
{
views.Remove();
worksheetPart.Worksheet.Save();
}
}
static void FixupTableParts(WorksheetPart worksheetPart, int numTableDefParts)
{
//Every table needs a unique id and name
foreach (TableDefinitionPart tableDefPart in worksheetPart.TableDefinitionParts)
{
tableId++;
tableDefPart.Table.Id = (uint)tableId;
tableDefPart.Table.DisplayName = "CopiedTable" + tableId;
tableDefPart.Table.Name = "CopiedTable" + tableId;
tableDefPart.Table.Save();
}
}
static WorksheetPart GetWorkSheetPart(WorkbookPart workbookPart, string sheetName)
{
//Get the relationship id of the sheetname
string relId = workbookPart.Workbook.Descendants<Sheet>()
.Where(s => s.Name.Value.Equals(sheetName))
.First()
.Id;
return (WorksheetPart)workbookPart.GetPartById(relId);
}
}
}
I found the solution and post it here maybe someone will get some help from it.
public static void MergeXSLX(string spreadSheetPathSource, string spreadSheetPathDestination)
{
//string[] staticSheets = new string[] { "Index", "Proj Info", "Project Report", "Cust Proj Rpt", "Issues Register", "Risk Register", "Change Register", "Milestones Register", "Add Optional Sheets ==>" };
string[] staticSheets = new string[] { "Summaries", "limits" };
FileStream spreadSheetStreamSource = null;
FileStream spreadSheetStreamDestination = null;
try
{
if (!File.Exists(spreadSheetPathSource)) throw new Exception("Source excel document not found!");
if (!File.Exists(spreadSheetPathDestination)) throw new Exception("Destination excel document not found!");
spreadSheetStreamSource = new FileStream(spreadSheetPathSource, FileMode.Open, FileAccess.Read);
spreadSheetStreamDestination = new FileStream(spreadSheetPathDestination, FileMode.Open, FileAccess.ReadWrite);
using (SpreadsheetDocument spreadsheetDocumentSource = SpreadsheetDocument.Open(spreadSheetStreamSource, false))
{
using (SpreadsheetDocument spreadsheetDocumentDestination = SpreadsheetDocument.Open(spreadSheetStreamDestination, true))
{
WorkbookPart workbookPartSource = spreadsheetDocumentSource.WorkbookPart;
WorkbookPart workbookPartDestination = spreadsheetDocumentDestination.WorkbookPart;
foreach (Sheet sheet in workbookPartSource.Workbook.Sheets)
{
if (staticSheets.ToList().Contains(sheet.Name))
{
uint replaced = 0;
int index = 0;
if (workbookPartDestination.Workbook.Sheets.Elements<Sheet>().Count(s => s.Name.ToString().Equals(sheet.Name)) == 1)
{
Sheet org;
foreach (Sheet s in workbookPartDestination.Workbook.Sheets.Elements<Sheet>())
{
if (s.Name.ToString().Equals(sheet.Name))
{
org = s;
break;
}
index++;
}
replaced = sheet.SheetId;
DeleteWorkSheet(workbookPartDestination, sheet.Name);
}
//WorkbookPart workbookPart = mySpreadsheet.WorkbookPart;
////Get the source sheet to be copied
WorksheetPart sourceSheetPart = GetWorkSheetPart(workbookPartSource, sheet.Name);
//Take advantage of AddPart for deep cloning
SpreadsheetDocument tempSheet = SpreadsheetDocument.Create(new MemoryStream(), spreadsheetDocumentDestination.DocumentType);
WorkbookPart tempWorkbookPart = tempSheet.AddWorkbookPart();
WorksheetPart tempWorksheetPart = tempWorkbookPart.AddPart<WorksheetPart>(sourceSheetPart);
if(workbookPartDestination.SharedStringTablePart == null)
{
workbookPartDestination.AddPart<SharedStringTablePart>(workbookPartSource.SharedStringTablePart);
}
//Add cloned sheet and all associated parts to workbook
WorksheetPart clonedSheet = workbookPartDestination.AddPart<WorksheetPart>(tempWorksheetPart);
//Table definition parts are somewhat special and need unique ids...so let's make an id based on count
int numTableDefParts = sourceSheetPart.GetPartsCountOfType<TableDefinitionPart>();
int tableId = numTableDefParts;
//Clean up table definition parts (tables need unique ids)
if (numTableDefParts != 0)
FixupTableParts(clonedSheet, numTableDefParts);
//There should only be one sheet that has focus
CleanView(clonedSheet);
var values = workbookPartSource.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ToArray();
Dictionary<uint, uint> cacheCellFormat = new Dictionary<uint, uint>();
Dictionary<uint, uint> cacheCellStyleFormat = new Dictionary<uint, uint>();
Dictionary<uint, uint> cacheBorder = new Dictionary<uint, uint>();
Dictionary<uint, uint> cacheFill = new Dictionary<uint, uint>();
Dictionary<uint, uint> cacheFont = new Dictionary<uint, uint>();
Dictionary<uint, uint> cacheNumberFormat = new Dictionary<uint, uint>();
foreach (Cell cell in clonedSheet.Worksheet.Descendants<Cell>())
{
if (cell.DataType != null && cell.DataType == CellValues.SharedString)
{
var ssindex = int.Parse(cell.CellValue.Text);
cell.CellValue = new CellValue(InsertSharedStringItem_(values[ssindex].InnerText, workbookPartDestination.SharedStringTablePart).ToString());
}
if (cell.StyleIndex != null)
{
cell.StyleIndex = GetCellFormat(workbookPartSource, workbookPartDestination, cacheCellFormat, cacheCellStyleFormat, cacheBorder, cacheFill, cacheFont, cacheNumberFormat, cell);
}
}
//Add new sheet to main workbook part
Sheets sheets = workbookPartDestination.Workbook.GetFirstChild<Sheets>();
Sheet copiedSheet = new Sheet
{
Name = sheet.Name,
Id = workbookPartDestination.GetIdOfPart(clonedSheet),
SheetId = (uint)sheets.ChildElements.Count + 1
};
if (replaced != 0)
{
copiedSheet.SheetId = replaced;
sheets.InsertAt(copiedSheet, index);
}
else
{
sheets.Append(copiedSheet);
}
//Save Changes
workbookPartDestination.Workbook.Save();
}
}
}
}
}
finally
{
if (spreadSheetStreamSource != null)
spreadSheetStreamSource.Close();
if (spreadSheetStreamDestination != null)
spreadSheetStreamDestination.Close();
}
}
private static uint GetCellFormat(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheCellFormat, Dictionary<uint, uint> cacheCellStyleFormat, Dictionary<uint, uint> cacheBorder, Dictionary<uint, uint> cacheFill, Dictionary<uint, uint> cacheFont, Dictionary<uint, uint> cacheNumberFormat, Cell cell)
{
uint cellFormatIndex, cellStyleFormatIndex;
if (cacheCellFormat.Keys.Contains(cell.StyleIndex.Value))
{
cellFormatIndex = cacheCellFormat[cell.StyleIndex.Value];
}
else
{
CellFormat cellFormat = workbookPartSource.WorkbookStylesPart.Stylesheet.CellFormats.Descendants<CellFormat>().ToList()[int.Parse(cell.StyleIndex)];
CellFormat cellFormatClone = CellFormatClone(workbookPartSource, workbookPartDestination, cacheBorder, cacheFill, cacheFont, cacheNumberFormat, cellFormat);
if (cellFormat.FormatId != 0)
{
if (cacheCellStyleFormat.Keys.Contains(cellFormat.FormatId.Value))
{
cellStyleFormatIndex = cacheCellStyleFormat[cellFormat.FormatId.Value];
}
else
{
CellFormat cellStyleFormat = workbookPartSource.WorkbookStylesPart.Stylesheet.CellStyleFormats.Descendants<CellFormat>().ToList()[int.Parse(cellFormat.FormatId)];
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.CellStyleFormats.Descendants<CellFormat>().ToList().Count > int.Parse(cellFormat.FormatId) &&
workbookPartDestination.WorkbookStylesPart.Stylesheet.CellStyleFormats.Descendants<CellFormat>().ToList()[int.Parse(cellFormat.FormatId)].OuterXml == cellStyleFormat.OuterXml)
{
cellStyleFormatIndex = (uint)int.Parse(cellFormat.FormatId);
}
else
{
CellFormat cellStyleFormatClone = CellFormatClone(workbookPartSource, workbookPartDestination, cacheBorder, cacheFill, cacheFont, cacheNumberFormat, cellStyleFormat);
workbookPartDestination.WorkbookStylesPart.Stylesheet.CellStyleFormats.Append(cellStyleFormatClone);
cellStyleFormatIndex = (uint)workbookPartDestination.WorkbookStylesPart.Stylesheet.CellStyleFormats.Descendants<CellFormat>().ToList().IndexOf(cellStyleFormatClone);
cacheCellStyleFormat.Add(cellFormat.FormatId.Value, cellStyleFormatIndex);
}
}
cellFormatClone.FormatId = cellStyleFormatIndex;
}
workbookPartDestination.WorkbookStylesPart.Stylesheet.CellFormats.Append(cellFormatClone);
cellFormatIndex = (uint)workbookPartDestination.WorkbookStylesPart.Stylesheet.CellFormats.Descendants<CellFormat>().ToList().IndexOf(cellFormatClone);
cacheCellFormat.Add(cell.StyleIndex.Value, cellFormatIndex);
}
return cellFormatIndex;
}
private static CellFormat CellFormatClone(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheBorder, Dictionary<uint, uint> cacheFill, Dictionary<uint, uint> cacheFont, Dictionary<uint, uint> cacheNumberFormat, CellFormat cellFormat)
{
CellFormat cellFormatClone = new CellFormat();
cellFormatClone.ApplyAlignment = cellFormat.ApplyAlignment;
cellFormatClone.ApplyBorder = cellFormat.ApplyBorder;
cellFormatClone.ApplyFill = cellFormat.ApplyFill;
cellFormatClone.ApplyFont = cellFormat.ApplyFont;
cellFormatClone.ApplyNumberFormat = cellFormat.ApplyNumberFormat;
cellFormatClone.ApplyProtection = cellFormat.ApplyProtection;
cellFormatClone.PivotButton = cellFormat.PivotButton;
cellFormatClone.QuotePrefix = cellFormat.QuotePrefix;
GetBorder(workbookPartSource, workbookPartDestination, cacheBorder, cellFormat, cellFormatClone);
GetFill(workbookPartSource, workbookPartDestination, cacheFill, cellFormat, cellFormatClone);
GetFont(workbookPartSource, workbookPartDestination, cacheFont, cellFormat, cellFormatClone);
GetNumberFormat(workbookPartSource, workbookPartDestination, cacheNumberFormat, cellFormat, cellFormatClone);
if (cellFormat.Protection != null)
cellFormatClone.Protection = (Protection)cellFormat.Protection.Clone();
if (cellFormat.Alignment != null)
cellFormatClone.Alignment = (Alignment)cellFormat.Alignment.Clone();
return cellFormatClone;
}
private static void GetNumberFormat(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheNumberFormat, CellFormat cellFormat, CellFormat cellFormatClone)
{
uint numberFormatIndex = 0;
if (cellFormat.NumberFormatId.Value != 0)
{
if (cacheNumberFormat.Keys.Contains(cellFormat.NumberFormatId.Value))
{
numberFormatIndex = cacheNumberFormat[cellFormat.NumberFormatId.Value];
}
else
{
NumberingFormat numberFormat = workbookPartSource.WorkbookStylesPart.Stylesheet.NumberingFormats.Descendants<NumberingFormat>().Where(nf => nf.NumberFormatId.Value == uint.Parse(cellFormat.NumberFormatId)).FirstOrDefault();
if (numberFormat != null)
{
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.NumberingFormats != null)
{
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.NumberingFormats.Descendants<NumberingFormat>().ToList().Count > int.Parse(cellFormat.NumberFormatId) &&
workbookPartDestination.WorkbookStylesPart.Stylesheet.NumberingFormats.Descendants<NumberingFormat>().ToList()[int.Parse(cellFormat.NumberFormatId)].OuterXml == numberFormat.OuterXml)
{
cellFormatClone.NumberFormatId = (uint)int.Parse(cellFormat.NumberFormatId);
return;
}
NumberingFormat nfclone = new NumberingFormat();
nfclone.FormatCode = numberFormat.FormatCode;
nfclone.NumberFormatId = workbookPartDestination.WorkbookStylesPart.Stylesheet.Descendants<NumberingFormat>().Max(nf => nf.NumberFormatId.Value) + 1;
workbookPartDestination.WorkbookStylesPart.Stylesheet.NumberingFormats.Append(nfclone);
numberFormatIndex = nfclone.NumberFormatId;
cacheNumberFormat.Add(cellFormat.NumberFormatId.Value, numberFormatIndex);
}
}
else
{
numberFormatIndex = cellFormat.NumberFormatId;
}
}
cellFormatClone.NumberFormatId = numberFormatIndex;
}
else
{
cellFormatClone.NumberFormatId = 0;
}
}
private static void GetFont(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheFont, CellFormat cellFormat, CellFormat cellFormatClone)
{
uint fontIndex;
if (cellFormat.FontId.Value != 0)
{
if (cacheFont.Keys.Contains(cellFormat.FontId.Value))
{
fontIndex = cacheFont[cellFormat.FontId.Value];
}
else
{
Font font = workbookPartSource.WorkbookStylesPart.Stylesheet.Fonts.Descendants<Font>().ToList()[int.Parse(cellFormat.FontId)];
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.Fonts.Descendants<Font>().ToList().Count > int.Parse(cellFormat.FontId) &&
workbookPartDestination.WorkbookStylesPart.Stylesheet.Fonts.Descendants<Font>().ToList()[int.Parse(cellFormat.FontId)].OuterXml == font.OuterXml)
{
cellFormatClone.FontId = (uint)int.Parse(cellFormat.FontId);
return;
}
Font fontClone = new Font();
if (font.Bold != null)
fontClone.Bold = (Bold)font.Bold.Clone();
if (font.Color != null)
fontClone.Color = (Color)font.Color.Clone();
if (font.Condense != null)
fontClone.Condense = (Condense)font.Condense.Clone();
if (font.Extend != null)
fontClone.Extend = (Extend)font.Extend.Clone();
if (font.FontCharSet != null)
fontClone.FontCharSet = (FontCharSet)font.FontCharSet.Clone();
if (font.FontName != null)
fontClone.FontName = (FontName)font.FontName.Clone();
if (font.FontScheme != null)
fontClone.FontScheme = (FontScheme)font.FontScheme.Clone();
if (font.FontSize != null)
fontClone.FontSize = (FontSize)font.FontSize.Clone();
if (font.Italic != null)
fontClone.Italic = (Italic)font.Italic.Clone();
if (font.Outline != null)
fontClone.Outline = (Outline)font.Outline.Clone();
if (font.Shadow != null)
fontClone.Shadow = (Shadow)font.Shadow.Clone();
if (font.Strike != null)
fontClone.Strike = (Strike)font.Strike.Clone();
if (font.Underline != null)
fontClone.Underline = (Underline)font.Underline.Clone();
if (font.VerticalTextAlignment != null)
fontClone.VerticalTextAlignment = (VerticalTextAlignment)font.VerticalTextAlignment.Clone();
if (font.FontFamilyNumbering != null)
fontClone.FontFamilyNumbering = (FontFamilyNumbering)font.FontFamilyNumbering.Clone();
workbookPartDestination.WorkbookStylesPart.Stylesheet.Fonts.Append(fontClone);
fontIndex = (uint)workbookPartDestination.WorkbookStylesPart.Stylesheet.Fonts.Descendants<Font>().ToList().IndexOf(fontClone);
cacheFont.Add(cellFormat.FontId.Value, fontIndex);
}
cellFormatClone.FontId = fontIndex;
}
else
{
cellFormatClone.FontId = 0;
}
}
private static void GetFill(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheFill, CellFormat cellFormat, CellFormat cellFormatClone)
{
uint fillIndex;
if (cellFormat.FillId.Value != 0)
{
if (cacheFill.Keys.Contains(cellFormat.FillId.Value))
{
fillIndex = cacheFill[cellFormat.FillId.Value];
}
else
{
Fill fill = workbookPartSource.WorkbookStylesPart.Stylesheet.Fills.Descendants<Fill>().ToList()[int.Parse(cellFormat.FillId)];
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.Fills.Descendants<Fill>().ToList().Count > int.Parse(cellFormat.FillId) &&
workbookPartDestination.WorkbookStylesPart.Stylesheet.Fills.Descendants<Fill>().ToList()[int.Parse(cellFormat.FillId)].OuterXml == fill.OuterXml)
{
cellFormatClone.FillId = (uint)int.Parse(cellFormat.FillId);
return;
}
Fill fillclone = new Fill();
if (fill.GradientFill != null)
fillclone.GradientFill = (GradientFill)fill.GradientFill.Clone();
if (fill.PatternFill != null)
fillclone.PatternFill = (PatternFill)fill.PatternFill.Clone();
workbookPartDestination.WorkbookStylesPart.Stylesheet.Fills.Append(fillclone);
fillIndex = (uint)workbookPartDestination.WorkbookStylesPart.Stylesheet.Fills.Descendants<Fill>().ToList().IndexOf(fillclone);
cacheFill.Add(cellFormat.FillId.Value, fillIndex);
}
cellFormatClone.FillId = fillIndex;
}
else
{
cellFormatClone.FillId = 0;
}
}
private static void GetBorder(WorkbookPart workbookPartSource, WorkbookPart workbookPartDestination, Dictionary<uint, uint> cacheBorder, CellFormat cellFormat, CellFormat cellFormatClone)
{
uint borderIndex;
if (cellFormat.BorderId.Value != 0)
{
if (cacheBorder.Keys.Contains(cellFormat.BorderId.Value))
{
borderIndex = cacheBorder[cellFormat.BorderId.Value];
}
else
{
Border border = workbookPartSource.WorkbookStylesPart.Stylesheet.Borders.Descendants<Border>().ToList()[int.Parse(cellFormat.BorderId)];
if (workbookPartDestination.WorkbookStylesPart.Stylesheet.Borders.Descendants<Border>().ToList().Count > int.Parse(cellFormat.BorderId) &&
workbookPartDestination.WorkbookStylesPart.Stylesheet.Borders.Descendants<Border>().ToList()[int.Parse(cellFormat.BorderId)].OuterXml == border.OuterXml)
{
cellFormatClone.BorderId = (uint)int.Parse(cellFormat.BorderId);
return;
}
Border borderclone = new Border();
if (border.StartBorder != null)
borderclone.StartBorder = (StartBorder)border.StartBorder.Clone();
if (border.EndBorder != null)
borderclone.EndBorder = (EndBorder)border.EndBorder.Clone();
if (border.LeftBorder != null)
borderclone.LeftBorder = (LeftBorder)border.LeftBorder.Clone();
if (border.RightBorder != null)
borderclone.RightBorder = (RightBorder)border.RightBorder.Clone();
if (border.TopBorder != null)
borderclone.TopBorder = (TopBorder)border.TopBorder.Clone();
if (border.BottomBorder != null)
borderclone.BottomBorder = (BottomBorder)border.BottomBorder.Clone();
if (border.DiagonalBorder != null)
borderclone.DiagonalBorder = (DiagonalBorder)border.DiagonalBorder.Clone();
if (border.VerticalBorder != null)
borderclone.VerticalBorder = (VerticalBorder)border.VerticalBorder.Clone();
if (border.HorizontalBorder != null)
borderclone.HorizontalBorder = (HorizontalBorder)border.HorizontalBorder.Clone();
workbookPartDestination.WorkbookStylesPart.Stylesheet.Borders.Append(borderclone);
borderIndex = (uint)workbookPartDestination.WorkbookStylesPart.Stylesheet.Borders.Descendants<Border>().ToList().IndexOf(borderclone);
cacheBorder.Add(cellFormat.BorderId.Value, borderIndex);
}
cellFormatClone.BorderId = borderIndex;
}
else
{
cellFormatClone.BorderId = 0;
}
}
private static int InsertSharedStringItem_(string text, SharedStringTablePart shareStringPart)
{
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
shareStringPart.SharedStringTable = new SharedStringTable();
}
int i = 0;
// Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
if (item.InnerText == text)
{
return i;
}
i++;
}
// The text does not exist in the part. Create the SharedStringItem and return its index.
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));
shareStringPart.SharedStringTable.Save();
return i;
}
private static void DeleteWorkSheet(WorkbookPart wbPart, string sheetToDelete)
{
string Sheetid = "";
// Get the pivot Table Parts
IEnumerable<PivotTableCacheDefinitionPart> pvtTableCacheParts = wbPart.PivotTableCacheDefinitionParts;
Dictionary<PivotTableCacheDefinitionPart, string> pvtTableCacheDefinationPart = new Dictionary<PivotTableCacheDefinitionPart, string>();
foreach (PivotTableCacheDefinitionPart Item in pvtTableCacheParts)
{
PivotCacheDefinition pvtCacheDef = Item.PivotCacheDefinition;
//Check if this CacheSource is linked to SheetToDelete
var pvtCahce = pvtCacheDef.Descendants<CacheSource>().Where(s => s.WorksheetSource.Sheet == sheetToDelete);
if (pvtCahce.Count() > 0)
{
pvtTableCacheDefinationPart.Add(Item, Item.ToString());
}
}
foreach (var Item in pvtTableCacheDefinationPart)
{
wbPart.DeletePart(Item.Key);
}
//Get the SheetToDelete from workbook.xml
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetToDelete).FirstOrDefault();
if (theSheet == null)
{
// The specified sheet doesn't exist.
}
//Store the SheetID for the reference
Sheetid = theSheet.SheetId;
// Remove the sheet reference from the workbook.
WorksheetPart worksheetPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));
theSheet.Remove();
// Delete the worksheet part.
wbPart.DeletePart(worksheetPart);
//Get the DefinedNames
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
if (definedNames != null)
{
foreach (DefinedName Item in definedNames)
{
// This condition checks to delete only those names which are part of Sheet in question
if (Item.Text.Contains(sheetToDelete + "!"))
Item.Remove();
}
}
// Get the CalculationChainPart
//Note: An instance of this part type contains an ordered set of references to all cells in all worksheets in the
//workbook whose value is calculated from any formula
CalculationChainPart calChainPart;
calChainPart = wbPart.CalculationChainPart;
if (calChainPart != null)
{
var calChainEntries = calChainPart.CalculationChain.Descendants<CalculationCell>().Where(c => c.SheetId == Sheetid);
foreach (CalculationCell Item in calChainEntries)
{
Item.Remove();
}
if (calChainPart.CalculationChain.Count() == 0)
{
wbPart.DeletePart(calChainPart);
}
}
// Save the workbook.
wbPart.Workbook.Save();
}
After spending many hours on the problem of copying the entire sheet, I finally found a solution. The CloneSheet method copies the entire sheet (content + style) to a new sheet with a new name.
static void CloneSheet(SpreadsheetDocument spreadsheetDocument, string sheetName, string clonedSheetName)
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart sourceSheetPart = GetWorkSheetPart(workbookPart, sheetName);
Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
SpreadsheetDocument tempSheet = SpreadsheetDocument.Create(new MemoryStream(), spreadsheetDocument.DocumentType);
WorkbookPart tempWorkbookPart = tempSheet.AddWorkbookPart();
WorksheetPart tempWorksheetPart = tempWorkbookPart.AddPart(sourceSheetPart);
WorksheetPart clonedSheet = workbookPart.AddPart(tempWorksheetPart);
Sheet copiedSheet = new Sheet();
copiedSheet.Name = clonedSheetName;
copiedSheet.Id = workbookPart.GetIdOfPart(clonedSheet);
copiedSheet.SheetId = (uint)sheets.ChildElements.Count + 1;
sheets.Append(copiedSheet);
}
the fact of assigning :
copiedSheet.SheetId = (uint)sheets.ChildElements.Count + 1;
is not correct because this SheetId could be taken.
instead you can write :
copiedSheet.SheetId = newSheetId (workbookPart);
where newsheetId is defined so :
private UInt32Value NewSheetId(WorkbookPart workbookPart)
{
UInt32Value resultat = 0;
foreach (Sheet sheet in workbookPart.Workbook.Descendants<Sheet>())
{
if (sheet.SheetId > resultat)
resultat = sheet.SheetId;
}
return resultat + 1;
}

Inserting text in Excel using Open Xml SDK and LINQ

I have been trying really hard but my excel sheet is not populating as per my expectations. If the content is having string datatype then sheet is showing '0' in place of that, howsoever hard I tried by using conversions. I am pasting my code below if any one can help me:
public static void WriteExcelDocument(string FilePath)
{
try
{
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(FilePath, true))
{
WorkbookPart workbookPart = spreadSheet.WorkbookPart;
IEnumerable<Sheet> Sheets = spreadSheet.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == "data");
if (Sheets.Count() == 0)
{
// The specified worksheet does not exist.
return;
}
string relationshipId = Sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)spreadSheet.WorkbookPart.GetPartById(relationshipId);
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
int index = 2;
SpectrumNewEntities context = new SpectrumNewEntities();
var q = from result in context.Appraisers
select result;
foreach (var g in q)
{
string Name = g.AppraiserName!=null?g.AppraiserName:String.Empty;
string city = g.City != null ? g.City : String.Empty;
string Address = g.Address != null ? g.Address : "NA";
int AppId = g.AppraiserAppraiserCompanyId != null ? (int)g.AppraiserAppraiserCompanyId : 0;
string email = g.Email != null ? g.Email : String.Empty;
Row contentRow = CreateContentRow(index, Name, city, Address, AppId,email);
index++;
sheetData.AppendChild(contentRow);
}
// Save the worksheet.
worksheetPart.Worksheet.Save();
}
}
catch (Exception)
{
throw;
}
}
private static Row CreateContentRow(int index, string Name, string city, string Address, int AppId, string email)
{
try
{
//Create new row
Row r = new Row();
r.RowIndex = (UInt32)index;
//First cell is a text cell, so create it and append it
Cell firstCell = CreateTextCell(headerColumns[0], Name, index);
r.AppendChild(firstCell);//
//create cells that contain data
for (int i = 1; i < headerColumns.Length; i++)
{
Cell c = new Cell();
c.CellReference = headerColumns[i] + index;
CellValue v = new CellValue();
if (i == 1)
{
v.Text = city.ToString();
}
if (i == 2)
{
v.Text = Address.ToString();
}
if (i == 3)
{
v.Text =AppId.ToString();
}
if (i == 4)
{
v.Text = email.ToString();
}
c.AppendChild(v);
r.AppendChild(c);
}
return r;
}
catch (Exception)
{
throw;
}
}
private static Cell CreateTextCell(string header, string Name,int index)
{
try
{
//Create a new inline string cell
Cell c = new Cell();
c.DataType = CellValues.InlineString;
c.CellReference = header + index;
//Add text to text cell
InlineString inlineString = new InlineString();
Text t = new Text();
t.Text = Name;
inlineString.AppendChild(t);
c.AppendChild(inlineString);
return c;
}
catch (Exception)
{
throw;
}
}
I am not getting why display is something like this?
Use the CreateTextCell method to add all the text cells to the row; like you are doing for the Name field.

Silverlight Datagrid - Export selected items to Excel

I have a datagrid in Silverlight that has a checkboxcolumn binded to a property.
<sdk:DataGridCheckBoxColumn x:Name="chkboxSelect" CanUserReorder="False" CanUserResize="False"
Binding="{Binding CopyToForecast}" />
I have also an export to excel from the datagrid which looks like this.
public static void ExportDataGrid(DataGrid dGrid)
{
SaveFileDialog objSFD = new SaveFileDialog() { DefaultExt = "csv", Filter = "CSV Files (*.csv)|*.csv|Excel XML (*.xml)|*.xml|All files (*.*)|*.*", FilterIndex = 1 };
if (objSFD.ShowDialog() == true)
{
string strFormat = objSFD.SafeFileName.Substring(objSFD.SafeFileName.IndexOf('.') + 1).ToUpper();
StringBuilder strBuilder = new StringBuilder();
if (dGrid.ItemsSource == null) return;
List<string> lstFields = new List<string>();
if (dGrid.HeadersVisibility == DataGridHeadersVisibility.Column || dGrid.HeadersVisibility == DataGridHeadersVisibility.All)
{
foreach (DataGridColumn dgcol in dGrid.Columns)
lstFields.Add(FormatField(dgcol.Header.ToString(), strFormat));
BuildStringOfRow(strBuilder, lstFields, strFormat);
}
foreach (object data in dGrid.ItemsSource)
{
lstFields.Clear();
foreach (DataGridColumn col in dGrid.Columns)
{
string strValue = "";
Binding objBinding = null;
if (col is DataGridBoundColumn)
objBinding = (col as DataGridBoundColumn).Binding;
if (col is DataGridTemplateColumn)
{
//This is a template column... let us see the underlying dependency object
DependencyObject objDO = (col as DataGridTemplateColumn).CellTemplate.LoadContent();
FrameworkElement oFE = (FrameworkElement)objDO;
FieldInfo oFI = oFE.GetType().GetField("TextProperty");
if (oFI != null)
{
if (oFI.GetValue(null) != null)
{
if (oFE.GetBindingExpression((DependencyProperty)oFI.GetValue(null)) != null)
objBinding = oFE.GetBindingExpression((DependencyProperty)oFI.GetValue(null)).ParentBinding;
}
}
}
if (objBinding != null)
{
if (objBinding.Path.Path != "")
{
PropertyInfo pi = data.GetType().GetProperty(objBinding.Path.Path);
if (pi != null) strValue = pi.GetValue(data, null).ToString();
}
if (objBinding.Converter != null)
{
if (strValue != "")
strValue = objBinding.Converter.Convert(strValue, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();
else
strValue = objBinding.Converter.Convert(data, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();
}
}
lstFields.Add(FormatField(strValue, strFormat));
}
BuildStringOfRow(strBuilder, lstFields, strFormat);
}
StreamWriter sw = new StreamWriter(objSFD.OpenFile());
if (strFormat == "XML")
{
//Let us write the headers for the Excel XML
}
sw.Write(strBuilder.ToString());
if (strFormat == "XML")
{
sw.WriteLine("</Table>");
sw.WriteLine("</Worksheet>");
sw.WriteLine("</Workbook>");
}
sw.Close();
}
}
how do I export only the selected (checked) rows from the datagrid to excel?
just set the grid.Itemsource to the selected values of your binding property and wham. it's done.

Categories

Resources