C#: OpenXML cannot get columns name print into excel file - excel

This is a console application trying to print data from datatable to excel file using open XML lib. I have also provided datatable code for reference.
class ProgramCheck
{
private static void Main()
{
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(#"C:\Users\nilam\Desktop\Work\project\GeneratedExcel.xlsx", SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "TestSheet2"
};
sheets.Append(sheet);
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
DataTable dt = Data.SampleData();
foreach (DataRow item in dt.Rows)
{
Row row = new Row();
for (int i = 0; i < item.ItemArray.Length; i++)
{
foreach (DataColumn itemCol in dt.Columns)
{
Columns col = new Columns();
Cell cell1 = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
col.Append(cell1);
Cell cell = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
row.Append(cell);
}
}
sheetData.Append(row);
}
workbookPart.Workbook.Save();
spreadsheetDocument.Close();
}
}
Code for row works fine, but when I try to loop through columns for heading, it does not append anything. I am using openXML to get data from the data table and output it into an excel file.
This is datatable (data.cs)
class Data
{
public static DataTable SampleData()
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Name");
dt.Columns.Add("Salary");
dt.Rows.Add("01", "Anis", "1000");
dt.Rows.Add("02", "AK", "2000");
dt.Rows.Add("03", "Mak", "3000");
return dt;
}
}
I have looked at the documentation of openXML but could not find anything so far.
[![enter image description here][1]][1]
enter code here
[1]: https://i.stack.imgur.com/EaPLh.png

I solved this...this is for someone who needs help. This code can be more refined you are welcome to do so and paste it.
SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(#"C:\Users\nilam\Desktop\Work\project\GeneratedExcel.xlsx", SpreadsheetDocumentType.Workbook);
WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
Sheet sheet = new Sheet()
{
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "TestSheet2"
};
sheets.Append(sheet);
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
DataTable dt = Data.SampleData();
//this is for Columns heading
Row rowHeading = new Row();
for (int j = 0; j < dt.Columns.Count; j++)
{
Cell cell1 = new Cell()
{
CellValue = new CellValue(dt.Columns[j].ColumnName.ToString()),
DataType = CellValues.String
};
rowHeading.Append(cell1);
}
sheetData.Append(rowHeading);
//this is for row content
foreach (DataRow item in dt.Rows)
{
Row row = new Row();
for (int i = 0; i < item.ItemArray.Length; i++)
{
Cell cell = new Cell()
{
CellValue = new CellValue(item[i].ToString()),
DataType = CellValues.String
};
row.Append(cell);
}
sheetData.Append(row);
}
workbookPart.Workbook.Save();
spreadsheetDocument.Close();
}

Related

The ExcelPackage object does not return sheets

I am trying to upload an excel file to a hosted Blazor webassembly application, for which I am using the following code:
string path= #"D:\Otros\LibrosExcel\ReferenciasDotación.xls";
FileInfo fileInfo = new FileInfo(path);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage excelPackage = new OfficeOpenXml.ExcelPackage(fileInfo))
{
//loop all worksheets
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.FirstOrDefault();
//loop all rows
for (int i = 1; i <= worksheet.Dimension.End.Row; i++)
{
//loop all columns in a row
for (int j = 1; j <= worksheet.Dimension.End.Column; j++)
{
//add the cell data to the List
if (worksheet.Cells[i, j].Value != null)
{
excelData.Add(worksheet.Cells[i, j].Value.ToString());
}
}
}
}
return excelData;
but the line of code
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets.FirstOrDefault ();
returns null

Sql Data to Excel File with Excel connection in SSIS

I want to know that is there a chance to save Sql data to excel file without using Excel destination task and without using Excel connection in Script task.
If any answer please help me.
Thank You.
I found a way to import SQL data to Excel sheet without Excel task and excel connection of ADO.net or any SSIS Excel connections. I did it in a script task. I used documentformat.openxml package. I installed openxml package in NuGet manager. Then It didn't work showing some errors. When I opened the code reference was sowing some error. Then, I changed the reference path of the package manually and tried. It worked. Hope it would help someone.
Thank You,
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
namespace DataToExcel
{
class Program
{
static void Main(string[] args)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Create(#"E:\Work\One.xlsx", SpreadsheetDocumentType.Workbook))
{
string connString = "Data Source=localhost;Initial Catalog=School;Integrated Security=True;";//Windows authentication
SqlConnection sqlConn = new SqlConnection(connString);
sqlConn.Open();
SqlCommand cmd = new SqlCommand("Test", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
sqlConn.Close();
List<string> header = new List<string>();
int count = dt.Rows.Count;
foreach (DataColumn column in dt.Columns)
{
header.Add(column.ColumnName);
}
//Here is the code for Excel saving.
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Sheet1" };
sheets.Append(sheet);
Row headerRow = new Row();
foreach (var item in header)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(item);
headerRow.AppendChild(cell);
}
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in dt.Rows)
{
Row newRow = new Row();
foreach (String col in header)
{
Cell cell = new Cell();
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(dsrow[col].ToString());
newRow.AppendChild(cell);
}
sheetData.AppendChild(newRow);
}
workbookPart.Workbook.Save();
}
}
}
}

How to edit an excel sheet and give background color to excel sheet cells using open xml?

I had a requirement of reading a excel sheet and change the color of some specific cells.
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
{
WorksheetPart wbPart = spreadSheet.WorkbookPart.WorksheetParts.FirstOrDefault();
Row row1 = getRow(1, wbPart);
foreach (Cell c2 in row1.Elements<Cell>())
{
if (c2.CellReference.Value == "G1")
{
AddbackgroundFormat(spreadSheet, c2, "56BEFB");
}
}
}
//Getting the row using row index
static Row getRow(uint rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
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);
}
return row;
}
//Adding styles two cells using the color passed
static void AddbackgroundFormat(SpreadsheetDocument document, Cell c, string colorCode)
{
Fills fs = AddFill(document.WorkbookPart.WorkbookStylesPart.Stylesheet.Fills, colorCode);
AddCellFormat(document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats, document.WorkbookPart.WorkbookStylesPart.Stylesheet.Fills);
c.StyleIndex = (UInt32)(document.WorkbookPart.WorkbookStylesPart.Stylesheet.CellFormats.Elements<CellFormat>().Count() - 1);
}
static Fills AddFill(Fills fills1, string colorCode)
{
Fill fill1 = new Fill();
PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.Solid };
ForegroundColor foregroundColor1 = new ForegroundColor() { Rgb = colorCode };
//BackgroundColor backgroundColor1 = new BackgroundColor() { Indexed = (UInt32Value)64U };
patternFill1.Append(foregroundColor1);
// patternFill1.Append(backgroundColor1);
fill1.Append(patternFill1);
fills1.Append(fill1);
return fills1;
}
static void AddCellFormat(CellFormats cf, Fills fs)
{
CellFormat cellFormat2 = new CellFormat() { NumberFormatId = 0, FontId = 0, FillId = (UInt32)(fs.Elements<Fill>().Count() - 1), BorderId = 0, FormatId = 0, ApplyFill = true };
cf.Append(cellFormat2);
}

Selenium Webdriver How to select records from table by fetching Excel Input

im struggeling for below scenario.
Application displayed records of 100 suppliers in one table have three columns namely as ID,Company name and Subscription name.
i want to take input from my excel sheet say company name"xyz" and using that input i have to click on subscription name details link so application will navigates me next page.
Sample code i have created as below:
`public static void main(String[] args) throws BiffException, IOException, Exception {
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
//Workbook location
Workbook wBook = Workbook.getWorkbook(new File("C:\Users\amit.bhagwat\Documents\TestData\SampleData.xls"));
//get sheet
jxl.Sheet Sheet = wBook.getSheet(0);
//loop
for(int i=1; i<Sheet.getRows(); i++)
{
driver.get("http://206.132.42.243/Web");
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//input[#id='UserName']")).sendKeys(Sheet.getCell(0, i).getContents());
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//input[#id='Password']")).sendKeys(Sheet.getCell(1, i).getContents());
driver.findElement(By.xpath("//input[#id='Password']")).sendKeys(Sheet.getCell(1, i).getContents());
Thread.sleep(40);
driver.findElement(By.xpath("//input[#name='Login']")).click();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[contains(text(),'Task')]")).click();
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[contains(text(),'Data Checking')]")).click();
jxl.Sheet Sheet2 = wBook.getSheet(0);
WebElement kancheck = driver.findElement(By.name("Grant & Brown"));
kancheck.click();
System.out.println(kancheck.isSelected());
driver.findElement(By.xpath("//a[contains(text(),'Data Checking')]")).sendKeys(Sheet2.getCell(1, i).getContents());
Thread.sleep(40);` enter code here
As far as I could understand, you are trying to read the file from a remote location and then read the information from it. It would be a good practice if you can use Apache POI library to read contents at run-time.
In my project, I read all the contents from an excel sheet usingApache POI library to set the values of my variables. Here is a code snippet on how i achieved it. Hopefully this will guide you to a proper solution. :)
public void readExcelDoc() throws FileNotFoundException, IOException
{
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("excelDoc//scripts.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFRow row = null;
HSSFCell cell = null;
int rows = 0; // No of rows
// rows = sheet.getPhysicalNumberOfRows();
rows = sheet.getLastRowNum();
int cols = 2; // No of columns
int tmp = 0;
// This trick ensures that we get the data properly even if it doesn't start from first few rows
for(int i = 0; i < 10 || i < rows; i++) {
row = sheet.getRow(i);
if(row != null) {
tmp = sheet.getRow(i).getPhysicalNumberOfCells();
if(tmp > cols) cols = tmp;
}
}
int testRowNo = 0;
String rowName = "Test Name";
String columnValue = " ";
//Iterate through Row and columns here. Excluding 1st row for title names
for(int r = 1; r <= rows; r++) {
row = sheet.getRow(r);
if(row != null) {
//Browse through columns using c
for(int c = 0; c < cols; c++) {
if(c==0) //Only taking data from Cell 0; Ignoring any other inputs
{
cell = row.getCell((short)c);
try
{
if(cell.getStringCellValue().contains(rowName))
{
testRowNo =row.getRowNum();
}
if(testRowNo > 0 )
{
if(cell.getColumnIndex() == 0 && row.getRowNum() > testRowNo && cell.getStringCellValue().length() !=0)
{
try{
String cellValue = cell.getStringCellValue().toLowerCase();
//System.out.println(cellValue);
scriptType.add(cellValue);
}
catch(IllegalStateException e)
{
e.printStackTrace();
scriptType.add(cell.getStringCellValue());
}
}
}
}
catch(NullPointerException e)
{
}
}
if(c==1)
{
cell = row.getCell((short)c); //this sets the column number
if(testRowNo == 0)
{
try{
String cellValue = cell.getStringCellValue();
//System.out.println(cellValue);
columnValue = cellValue;
}
catch(IllegalStateException e)
{
String cellValue = cell.toString();
columnValue = cellValue;
}
catch(NullPointerException e)
{
String cellValue = nodata;
columnValue = cellValue;
}
}
}
if(c==2)
{
cell = row.getCell((short)c); //this sets the column number
if(testRowNo == 0)
{
try{
String cellValue = cell.getStringCellValue();
//System.out.println(cellValue);
inputParameters.put(cellValue, columnValue);
}
catch(IllegalStateException e)
{
String cellValue = cell.toString();
inputParameters.put(cellValue, columnValue);
}
catch(NullPointerException e)
{
String cellValue = nodata;
inputParameters.put(cellValue, columnValue);
}
}
}
}
}
}
System.out.println("---------The parameters set from excel are : ---------");
#SuppressWarnings("rawtypes")
Iterator iterator = inputParameters.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next().toString();
String value = inputParameters.get(key).toString();
System.out.println(key + " : " + value);
}
}

How do you use the OpenXML API to read a Table from an Excel spreadsheet?

I've read a bunch of stuff on the web about how to get at cell data using the OpenXML API. But there's really not much out there that's particularly straightforward. Most seems to be about writing to SpreadsheetML, not reading... but even that doesn't help much.
I've got a spreadsheet that has a table in it. I know what the table name is, and I can find out what sheet it's on, and what columns are in the table. But I can't figure out how to get a collection of rows back that contain the data in the table.
I've got this to load the document and get a handle to the workbook:
SpreadsheetDocument document = SpreadsheetDocument.Open("file.xlsx", false);
WorkbookPart workbook = document.WorkbookPart;
I've got this to find the table/sheet:
Table table = null;
foreach (Sheet sheet in workbook.Workbook.GetFirstChild<Sheets>())
{
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);
foreach (TableDefinitionPart tableDefinitionPart in worksheetPart.TableDefinitionParts)
{
if (tableDefinitionPart.Table.DisplayName == this._tableName)
{
table = tableDefinitionPart.Table;
break;
}
}
}
And I can iterate over the columns in the table by foreaching over table.TableColumns.
To read an Excel 2007/2010 spreadsheet with OpenXML API is really easy. Somehow even simpler than using OleDB as we always did as quick & dirty solution. Moreover it's not just simple but verbose, I think to put all the code here isn't useful if it has to be commented and explained too so I'll write just a summary and I'll link a good article. Read this article on MSDN, it explain how to read XLSX documents in a very easy way.
Just to summarize you'll do this:
Open the SpreadsheetDocument with SpreadsheetDocument.Open.
Get the Sheet you need with a LINQ query from the WorkbookPart of the document.
Get (finally!) the WorksheetPart (the object you need) using the Id of the Sheet.
In code, stripping comments and error handling:
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
{
Sheet sheet = document.WorkbookPart.Workbook
.Descendants<Sheet>()
.Where(s => s.Name == sheetName)
.FirstOrDefault();
WorksheetPart sheetPart =
(WorksheetPart)(document.WorkbookPart.GetPartById(theSheet.Id));
}
Now (but inside the using!) what you have to do is just to read a cell value:
Cell cell = sheetPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == addressName).FirstOrDefault();
If you have to enumerate the rows (and they are a lot) you have first to obtain a reference to the SheetData object:
SheetData sheetData = sheetPart.Worksheet.Elements<SheetData>().First();
Now you can ask for all the rows and cells:
foreach (Row row in sheetData.Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
string text = cell.CellValue.Text;
// Do something with the cell value
}
}
To simply enumerate a normal spreadsheet you can use Descendants<Row>() of the WorksheetPart object.
If you need more resources about OpenXML take a look at OpenXML Developer, it contains a lot of good tutorials.
There are probably many better ways to code this up, but I slapped this together because I needed it, so hopefully it will help some others.
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Packaging;
private static DataTable genericExcelTable(FileInfo fileName)
{
DataTable dataTable = new DataTable();
try
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fileName.FullName, false))
{
Workbook wkb = doc.WorkbookPart.Workbook;
Sheet wks = wkb.Descendants<Sheet>().FirstOrDefault();
SharedStringTable sst = wkb.WorkbookPart.SharedStringTablePart.SharedStringTable;
List<SharedStringItem> allSSI = sst.Descendants<SharedStringItem>().ToList<SharedStringItem>();
WorksheetPart wksp = (WorksheetPart)doc.WorkbookPart.GetPartById(wks.Id);
foreach (TableDefinitionPart tdp in wksp.TableDefinitionParts)
{
QueryTablePart qtp = tdp.QueryTableParts.FirstOrDefault<QueryTablePart>();
Table excelTable = tdp.Table;
int colcounter = 0;
foreach (TableColumn col in excelTable.TableColumns)
{
DataColumn dcol = dataTable.Columns.Add(col.Name);
dcol.SetOrdinal(colcounter);
colcounter++;
}
SheetData data = wksp.Worksheet.Elements<SheetData>().First();
foreach (DocumentFormat.OpenXml.Spreadsheet.Row row in data)
{
if (isInTable(row.Descendants<Cell>().FirstOrDefault(), excelTable.Reference, true))
{
int cellcount = 0;
DataRow dataRow = dataTable.NewRow();
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.DataType != null && cell.DataType.InnerText == "s")
{
dataRow[cellcount] = allSSI[int.Parse(cell.CellValue.InnerText)].InnerText;
}
else
{
dataRow[cellcount] = cell.CellValue.Text;
}
cellcount++;
}
dataTable.Rows.Add(dataRow);
}
}
}
}
//do whatever you want with the DataTable
return dataTable;
}
catch (Exception ex)
{
//handle an error
return dataTable;
}
}
private static Tuple<int, int> returnCellReference(string cellRef)
{
int startIndex = cellRef.IndexOfAny("0123456789".ToCharArray());
string column = cellRef.Substring(0, startIndex);
int row = Int32.Parse(cellRef.Substring(startIndex));
return new Tuple<int,int>(TextToNumber(column), row);
}
private static int TextToNumber(string text)
{
return text
.Select(c => c - 'A' + 1)
.Aggregate((sum, next) => sum * 26 + next);
}
private static bool isInTable(Cell testCell, string tableRef, bool headerRow){
Tuple<int, int> cellRef = returnCellReference(testCell.CellReference.ToString());
if (tableRef.Contains(":"))
{
int header = 0;
if (headerRow)
{
header = 1;
}
string[] tableExtremes = tableRef.Split(':');
Tuple<int, int> startCell = returnCellReference(tableExtremes[0]);
Tuple<int, int> endCell = returnCellReference(tableExtremes[1]);
if (cellRef.Item1 >= startCell.Item1
&& cellRef.Item1 <= endCell.Item1
&& cellRef.Item2 >= startCell.Item2 + header
&& cellRef.Item2 <= endCell.Item2) { return true; }
else { return false; }
}
else if (cellRef.Equals(returnCellReference(tableRef)))
{
return true;
}
else
{
return false;
}
}

Resources