I am using C# with Open XML Format SDK 2.0, Trying to write an Excel report file. My problem is when I cross the Z column (reaching AA) the file goes corrupted and cannot be open manually by the user.
Any ideas?
static void Main(string[] args)
{
PortfolioReport report = new PortfolioReport("Keywords");
report.CreateReport();
}
public PortfolioReport(string client)
{
string newFileName = path + client + ".xlsx";
if (File.Exists(newFileName))
{
File.Delete(newFileName);
}
FileInfo newFile = new FileInfo(newFileName);
using (ExcelPackage package = new ExcelPackage(newFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Keywords");
package.Save();
}
document = SpreadsheetDocument.Open(newFileName, true);
wbPart = document.WorkbookPart;
}
static readonly string[] Columns = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH" };
public static string IndexToColumn(int index)
{
if (index < 0)
throw new IndexOutOfRangeException("index must be a positive number");
return Columns[index];
}
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
// Create a new Portfolio report
public void CreateReport()
{
string wsName = "Report Summary";
wbPart.Workbook.Descendants<Sheet>().FirstOrDefault().Name = wsName;
var currentUser = UsersInfo.Keywords;
//set the domainAge
KeywordsModule.SetYearsAndMonths(currentUser.Keywords);
//set the url site relevency in words
KeywordsModule.SetAverageUrlSiteRelevencyLiteral(currentUser.Keywords);
//set a model for the excel which will convert the keyword to the custom model according to gui names
List<KeywordModelForExcelExport> keywordsForExports = KeywordsModule.PrepreKeywordSforExport(currentUser.Keywords);
//we set the column headings
var properties = typeof(KeywordModelForExcelExport).GetProperties();
for (int i = 0; i < properties.Length; i++)
{
var cell = IndexToColumn(i) + 1;
UpdateValue(wsName, cell, properties[i].Name, 0, true);
}
//now we set the keyword values
int row = 2;
foreach (var keywordForExport in keywordsForExports)
{
for (int i = 0; i < properties.Length; i++)
{
var val = GetPropValue(keywordForExport, properties[i].Name);
var cell = IndexToColumn(i) + row;
if (val != null)
UpdateValue(wsName, cell, val.ToString(), 0, true);
}
row++;
}
// All done! Close and save the document.
document.Close();
}
// Given a Worksheet and an address (like "AZ254"), either return a cell reference, or
// create the cell reference and return it.
private Cell InsertCellInWorksheet(Worksheet ws, string addressName)
{
SheetData sheetData = ws.GetFirstChild<SheetData>();
Cell cell = null;
UInt32 rowNumber = GetRowIndex(addressName);
Row row = GetRow(sheetData, rowNumber);
// If the cell you need already exists, return it.
// If there is not a cell with the specified column name, insert one.
Cell refCell = row.Elements<Cell>().
Where(c => c.CellReference.Value == addressName).FirstOrDefault();
if (refCell != null)
{
cell = refCell;
}
else
{
cell = CreateCell(row, addressName);
}
return cell;
}
private Cell CreateCell(Row row, String address)
{
Cell cellResult;
Cell refCell = null;
// Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference.Value, address, true) > 0)
{
refCell = cell;
break;
}
}
cellResult = new Cell();
cellResult.CellReference = address;
row.InsertBefore(cellResult, refCell);
return cellResult;
}
private Row GetRow(SheetData wsData, UInt32 rowIndex)
{
var row = wsData.Elements<Row>().
Where(r => r.RowIndex.Value == rowIndex).FirstOrDefault();
if (row == null)
{
row = new Row();
row.RowIndex = rowIndex;
wsData.Append(row);
}
return row;
}
private UInt32 GetRowIndex(string address)
{
string rowPart;
UInt32 l;
UInt32 result = 0;
for (int i = 0; i < address.Length; i++)
{
if (UInt32.TryParse(address.Substring(i, 1), out l))
{
rowPart = address.Substring(i, address.Length - i);
if (UInt32.TryParse(rowPart, out l))
{
result = l;
break;
}
}
}
return result;
}
public bool UpdateValue(string sheetName, string addressName, string value, UInt32Value styleIndex, bool isString)
{
// Assume failure.
bool updated = false;
Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).FirstOrDefault();
if (sheet != null)
{
Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
Cell cell = InsertCellInWorksheet(ws, addressName);
if (isString)
{
// Either retrieve the index of an existing string,
// or insert the string into the shared string table
// and get the index of the new item.
int stringIndex = InsertSharedStringItem(wbPart, value);
cell.CellValue = new CellValue(stringIndex.ToString());
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
}
else
{
cell.CellValue = new CellValue(value);
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
}
if (styleIndex > 0)
cell.StyleIndex = styleIndex;
// Save the worksheet.
ws.Save();
updated = true;
}
return updated;
}
// Given the main workbook part, and a text value, insert the text into the shared
// string table. Create the table if necessary. If the value already exists, return
// its index. If it doesn't exist, insert it and return its new index.
private int InsertSharedStringItem(WorkbookPart wbPart, string value)
{
int index = 0;
bool found = false;
var stringTablePart = wbPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
// If the shared string table is missing, something's wrong.
// Just return the index that you found in the cell.
// Otherwise, look up the correct text in the table.
if (stringTablePart == null)
{
// Create it.
stringTablePart = wbPart.AddNewPart<SharedStringTablePart>();
stringTablePart.SharedStringTable = new SharedStringTable();
}
var stringTable = stringTablePart.SharedStringTable;
// if (stringTable == null)
// {
// stringTable = new SharedStringTable();
// }
// Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
foreach (SharedStringItem item in stringTable.Elements<SharedStringItem>())
{
if (item.InnerText == value)
{
found = true;
break;
}
index += 1;
}
if (!found)
{
stringTable.AppendChild(new SharedStringItem(new Text(value)));
stringTable.Save();
}
return index;
}
Your ordering is broken in CreateCell for cell references after Z. You are currently using string.Compare but that will do an alpha comparison meaning AA1 is before Z1 rather than after it.
There are various ways you could fix this - one way would be to convert the cellReference to a column index and then compare those instead of comparing the cell references directly. For example:
private static int? GetColumnIndex(string cellRef)
{
if (string.IsNullOrEmpty(cellRef))
return null;
cellRef = cellRef.ToUpper();
int columnIndex = -1;
int mulitplier = 1;
foreach (char c in cellRef.ToCharArray().Reverse())
{
if (char.IsLetter(c))
{
columnIndex += mulitplier * ((int)c - 64);
mulitplier = mulitplier * 26;
}
}
return columnIndex;
}
Then instead of
if (string.Compare(cell.CellReference.Value, address, true) > 0)
{
refCell = cell;
break;
}
You can do
if (GetColumnIndex(cell.CellReference.Value) > GetColumnIndex(address))
{
refCell = cell;
break;
}
Related
I built a winform project. This project open a mhtml file, then, he display the datagrid and remove the empty column.
i used much time "invoke" in my code. I would like to know how can i put this data into a DataTable or List and then binded the grid to it.
Here is the code :
{
public partial class Form1 : Form
{
private readonly string ConvertedFileName = "page.html";
private readonly List<string> ColumnsToSeparate = new List<string>() { "life limit", "interval" }; // Delete these columns
private readonly List<string> ExtraColumnsToAdd = new List<string>() { "Calendar", "Flight Hours", "Landing" }; // Add these columns
public Form1()
{
InitializeComponent();
this.Text = $"MhtmlTablesHunter v{Application.ProductVersion}";
}
//browse for specific file type , in this case its .mhtml
private void btnBrowse_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Title = "Please choose the MHTML file";
openFileDialog.Filter = "MHTML files (*.mhtml)|*.mhtml;"; //the file type specified here
openFileDialog.RestoreDirectory = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
textBoxSourceFile.Text = openFileDialog.FileName;
checkAndExtractTable();
}
}
}
private void checkAndExtractTable()
{
string sourcePath = textBoxSourceFile.Text;
if (!string.IsNullOrEmpty(sourcePath)) //check if the input file path is not empty
{
if (File.Exists(sourcePath)) //check if the input file path is exists
{
Task.Run(async () => await ExtractTable(sourcePath)); //run the extraction process in a thread for the UI to be more responsive
}
else
{
MessageBox.Show("Source file doesn't exist.");
}
}
else
{
MessageBox.Show("Please select the source file.");
}
}
//This part concern the headers, rows and columns
public async Task<string> ExtractTable(string sourcePath)
{
try
{
var doc = new HtmlAgilityPack.HtmlDocument();
var converter = new MimeConverter(); //converter used to convert mhtml file to html
if (File.Exists(ConvertedFileName)) //check if previously converted file is exist
{
File.Delete(ConvertedFileName); //delete the file
}
using (FileStream sourceStream = File.OpenRead(sourcePath))
{
using (FileStream destinationStream = File.Open("page.html", FileMode.Create))
{
await converter.Convert(sourceStream, destinationStream); //convert the file to html, it will be stored in the application folder
}
}
doc.Load(ConvertedFileName); //load the html
var tables = doc.DocumentNode.SelectNodes("//table"); //get all the tables
HtmlAgilityPack.HtmlNode table = null;
if (tables.Count > 0)
{
table = tables[tables.Count - 1]; //take the last table
}
if (table != null) //if the table exists
{
dataGridView1.Invoke((Action)delegate //we use delegate because we accessing the datagridview from a different thread
{
this.dataGridView1.Rows.Clear();
this.dataGridView1.Columns.Clear();
});
var rows = table.SelectNodes(".//tr"); //get all the rows
var nodes = rows[0].SelectNodes("th|td"); //get the header row values, first item will be the header row always
string LifeLimitColumnName = ColumnsToSeparate.Where(c => nodes.Any(n => n.InnerText.ToLower().Contains(c))).FirstOrDefault();
if (string.IsNullOrWhiteSpace(LifeLimitColumnName))
{
LifeLimitColumnName = "Someunknowncolumn";
}
List<string> headers = new List<string>();
for (int i = 0; i < nodes.Count; i++) // LOOP
{
headers.Add(nodes[i].InnerText);
if (!nodes[i].InnerText.ToLower().Contains(LifeLimitColumnName))
{
dataGridView1.Invoke((Action)delegate
{
dataGridView1.Columns.Add("", nodes[i].InnerText);
});
}
}
int indexOfLifeLimitColumn = headers.FindIndex(h => h.ToLower().Contains(LifeLimitColumnName));
if (indexOfLifeLimitColumn > -1)
{
foreach (var eh in ExtraColumnsToAdd)
{
dataGridView1.Invoke((Action)delegate
{
dataGridView1.Columns.Add("", eh); //add extra header to the datagridview
});
}
}
for (int i = 1; i < rows.Count; i++) ///loop through rest of the rows
{
var row = rows[i];
var nodes2 = row.SelectNodes("th|td"); //get all columns in the current row
List<string> values = new List<string>(); //list to store row values
for (int x = 0; x < nodes2.Count; x++)
{
//rowes.Cells[x].Value = nodes2[x].InnerText;
string cellText = nodes2[x].InnerText.Replace(" ", " ");
values.Add(cellText); //add the cell value in the list
}
// Factory for -> Calendar, Flight Hours, Landings
if (indexOfLifeLimitColumn > -1)
{
values.RemoveAt(indexOfLifeLimitColumn);
string lifeLimitValue = nodes2[indexOfLifeLimitColumn].InnerText.Replace(" ", " ");
string[] splittedValues = lifeLimitValue.Split(' ');
for (int y = 0; y < ExtraColumnsToAdd.Count; y++)
{
if (ExtraColumnsToAdd[y] == "Calendar")
{
string valueToAdd = string.Empty;
string[] times = new string[] { "Years", "Year", "Months", "Month", "Day", "Days" };
if (splittedValues.Any(s => times.Any(t => t == s)))
{
var timeFound = times.Where(t => splittedValues.Any(s => s == t)).FirstOrDefault();
int index = splittedValues.ToList().FindIndex(s => s.Equals(timeFound));
valueToAdd = $"{splittedValues[index - 1]} {timeFound}";
}
values.Add(valueToAdd);
}
else if (ExtraColumnsToAdd[y] == "Flight Hours")
{
string valueToAdd = string.Empty;
if (splittedValues.Any(s => s == "FH"))
{
int index = splittedValues.ToList().FindIndex(s => s.Equals("FH"));
valueToAdd = $"{splittedValues[index - 1]} FH";
}
values.Add(valueToAdd);
}
else
{
string valueToAdd = string.Empty;
if (splittedValues.Any(s => s == "LDG"))
{
int index = splittedValues.ToList().FindIndex(s => s.Equals("LDG"));
valueToAdd = $"{splittedValues[index - 1]} LDG";
}
values.Add(valueToAdd);
}
}
}
dataGridView1.Invoke((Action)delegate
{
this.dataGridView1.Rows.Add(values.ToArray()); //add the list as a row
});
}
//This code remove the empty row
dataGridView1.Invoke((Action)delegate
{
int[] rowDataCount = new int[dataGridView1.Columns.Count];
Array.Clear(rowDataCount, 0, rowDataCount.Length);
for (int row_i = 0; row_i < this.dataGridView1.RowCount; row_i++)
{
for (int col_i = 0; col_i < this.dataGridView1.ColumnCount; col_i++)
{
var cell = this.dataGridView1.Rows[row_i].Cells[col_i];
string cellText = cell.Value.ToString();
if (!String.IsNullOrWhiteSpace(cellText))
{
rowDataCount[col_i] += 1;
}
}
}
int removedCount = 0;
for (int index = 0; index < rowDataCount.Length; index++)
{
if (rowDataCount[index] == 0)
{
this.dataGridView1.Columns.RemoveAt(index - removedCount);
removedCount++;
}
}
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return string.Empty;
}
private void textBoxSourceFile_TextChanged(object sender, EventArgs e)
{
}
}
}
Somebody can help me please? thanks a lot !
I am using iText 7 for creating a table inside the PDF file.
My table must have only vertical border (left and right of each column) and in the first row of each page also topo border
and in the last row of each page also bottom border.
In each row there's only one columns that can be "rowspanned" on two lines (at max).
I have successfully created the table with repeated header on each page but in the last row of each page i can't draw the bottom border.
Problem can be approached in several ways.
I use a function GetCell to obtain a cell object and then add to table like this
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
pdf.SetDefaultPageSize(PageSize.A4.Rotate());
var document = new Document(pdf);
iText.Layout.Element.Table table;
...HEADER
table.AddHeaderCell(GetCell(1, 1, "V", dgv.Columns[i].HeaderText, "{0}", TextAlignment.CENTER, VerticalAlignment.TOP));
....AddHeaderCell for all columns
....init cycle
table.AddCell(GetCell(1, 1, "F", mystring, TextAlignment.CENTER, VerticalAlignment.TOP).SetBorder(null));
...ending cycle
document.Add(table);
document.close;
.....
and then iterate through all cells in table and applied left and right border to cells.
int numrows= table.GetNumberOfRows();
int numcols= table.GetNumberOfColumns();
for (int irow = 0; irow < numrows; irow++)
{
for (int icol = 0; icol < numcols; icol++)
{
try
{
Cell mycell = table.GetCell(irow,icol);
mycell.SetBorderRight(new SolidBorder(0.5f));
mycell.SetBorderLeft(new SolidBorder(0.5f));
}
catch (NullReferenceException)
{
}
}
}
The biggest difficulty is knowing if the line i'm writing is the last one on the page and another difficult is getting the cell value during the iterative cycle.
Considerations:
I can apply bottom border also in GetCell function in this case i should know in this phase if my row is the last in the page. I've tried with this but the result in not good
After cell adding i verify if there's enough space to write another row.
LayoutResult result = table.CreateRendererSubTree().SetParent(document.GetRenderer()).Layout(
new LayoutContext(new LayoutArea(1, new Rectangle(0, 0, 400, 1e4f))));
LayoutArea currentArea = document.GetRenderer().GetCurrentArea();
Rectangle rectangle = currentArea.GetBBox();
float verticalPosition = rectangle.GetHeight();
float docBottom = rectangle.GetBottom();
float TableHeight = result.GetOccupiedArea().GetBBox().GetHeight();
if (verticalPosition - TableHeight <= docBottom)
{
// document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
//Debug.Print("........................................Last Row splitted");
};
private static Cell GetCell(int cm, int rowspan, string ItsHeader, string mytext, TextAlignment mytextalign,
VerticalAlignment myvertalign) {
Cell cell = new Cell(rowspan, cm);
Paragraph p;
if (ItsHeader == "V") {
cell.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.LIGHT_GRAY);
cell.SetTextAlignment(mytextalign);
p = new Paragraph(String.Format("{0}", mytext)).SetFontSize(10);
cell.Add(p);
} else {
if (myvertalign == VerticalAlignment.MIDDLE) {
Div d = new Div();
d.SetVerticalAlignment(VerticalAlignment.MIDDLE);
p = new Paragraph(String.Format("{0}", mytext)).SetFontSize(8);
p.SetTextAlignment(mytextalign);
d.Add(p);
cell.Add(d);
} else {
cell.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.WHITE);
p = new Paragraph(String.Format("{0}", mytext)).SetFontSize(8);
p.SetTextAlignment(mytextalign);
p.SetMultipliedLeading(1.5f);
p.SetMarginTop(0);
cell.Add(p);
}
}
return cell;
}
Thanks for your time and suggestions.
I would obtain something like this
Example
Solved in this way.
I combined a few things that were giving me problems.
Table With Header Repeated in each page.
Table with borders.
Cell with only Left and Righe Border
Grand Total in last row in last page
For each first row in each page printed 2 Columns Values
The only condition is to define a variable in which to store the maximum height of the table within the page (horizontal orientation for me). If this height is exceeded, a page break is generated.
Thanks for time.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iText.IO.Image;
using iText.IO.Font;
using iText.IO.Font.Constants;
using iText.Kernel.Events;
using iText.Kernel.Font;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Kernel.Pdf.Xobject;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Layout;
using iText.Layout.Properties;
using iText.Layout.Renderer;
using Newtonsoft.Json;
using System.Collections.Specialized;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Web.UI.WebControls;
using System.Web;
using iText.IO.Source;
namespace PrintPDF7
{
public class PrintPDFNew
{
public string Stato = "";
private DataTable TableDati;
private static string ID = "1472";
private string Name = "XXXXXXX";
private static string PathImmagine = "";
private static Classi.DataJSON varJSON;
private static Classi.commonParamaters parametersReceveid;
public static string vName
{ get { return vName; }
set { vName = value; }
}
public static string vID
{
get { return vID; }
set { vID = value; }
}
public byte[] GetReport(HttpResponse response, string TipoOutput, string FileToSave, GridView myGrid, Classi.commonParamaters parCommons, string appPath, string ServerMapPath)
{
string mystring=null;
string fCUR = "{0:#,##0.00}";
int columns_numbers = 18;
PdfDocument pdf;
Memoryms ms=null;
PdfWriter writer;
parametersReceveid = parCommons;
PathImmagine = ServerMapPath + #"Images\logo.gif";
TextAlignment vCenter = TextAlignment.CENTER;
TextAlignment vLeft = TextAlignment.LEFT;
TextAlignment vRight = TextAlignment.RIGHT;
VerticalAlignment vTop = VerticalAlignment.TOP;
msReader r = new msReader(ServerMapPath + "APP_DATA/DATA_INI.TXT");
string jsonString = r.ReadToEnd();
varJSON = JsonConvert.DeserializeObject<Classi.DataJSON>(jsonString);
r.Close();
parametersReceveid.ID = Convert.ToInt32(((Label)myGrid.Rows[1].Cells[1].Controls[1]).Text);
ID = ((Label)myGrid.Rows[1].Cells[1].Controls[1]).Text;
vName = Name;
ms = new MemorymStream();
writer = new PdfWriter(ms);
pdf = new PdfDocument(writer);
pdf.SetDefaultPageSize(PageSize.A4.Rotate());
var document = new Document(pdf);
iText.Layout.Element.Table table;
table = MakeTable(columns_numberonne, pdf, document, ID, vName);
TableHeaderEventHandler handler = new TableHeaderEventHandler(table,document, ID, Name);
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, handler);
Footer footerHandler = new Footer();
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
// Calculate top margin to be sure that the table will fit the margin.
float topMargin = 20 + handler.GetTableHeight();
document.SetMargins(topMargin, 36, 36, 36);
GridView dgv = myGrid;
int dgvrowcount = dgv.Rows.Count;
int dgvcolumncount = dgv.Columns.Count;
MakeTableHeader(myGrid, table);
string printID = "V";
double Total=0; double TotalTax = 0; double TotalTax_Credit = 0;
Cell TheCell;
SubtotalHandler handlerTotals = new SubtotalHandler();
float HeightTable = 0;
float HeightHeader = 0;
float HeightTableParz = 0;
HeightHeader = GetHeightTable(table, document);
for (int i = 0; i < dgvrowcount; i++)
{
if (float.Parse(varJSON.Height_MAX_Table) < HeightTable + HeightHeader)
{
HeightTableParz = HeightTable;
BordersCells(table, "ROW","F");
BordersCells(table, "HEADER","F");
BordersCells(table, "FOOTER","F");
document.Add(table);
document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
printID = "V";
HeightTable = 0;
table = null;
handlerTotals = new SubtotalHandler();
table = MakeTable(columns_numberonne, pdf, document, ID, vName);
MakeTableHeader(myGrid, table);
}
else
{
printID = (i == 0 ? "V" : "F");
}
for (int c = 0; c < dgvcolumncount; c++)
{
switch (dgv.Columns[c].HeaderText)
{
case "ID":
TheCell = GetCell(1, 1, "F", (printID == "V" ? ID : ""), "{0}", vCenter, vTop).SetBorder(null);
table.AddCell(TheCell);
table.AddCell(GetCell(3, 1, "F", (printID == "V" ? vName : ""), "{0}", vCenter, vTop).SetBorder(null));
break;
case "Year Pag.":
case "Year Rif.":
case "Cause":
mystring = ((Label)myGrid.Rows[i].Cells[c].Controls[1]).Text;
table.AddCell(GetCell(1, 1, "F", mystring, "{0}", vCenter, vTop).SetBorder(null));
break;
case "Desc":
mystring = ((Label)myGrid.Rows[i].Cells[c].Controls[1]).Text;
table.AddCell(GetCell(5, 1, "F", mystring, "{0}", vCenter, vTop).SetBorder(null));
break;
case "Amount":
mystring = ((Label)myGrid.Rows[i].Cells[c].Controls[1]).Text.Replace(" €", "");
TheCell = GetCell(2, 1, "F", String.Format(fCUR, Convert.ToDouble(mystring)), "{0}", vCenter, vTop).SetBorder(null);
TheCell.SetNextRenderer(new SubtotalHandlerAwareCellRenderer(TheCell, handlerTotals, "I", Convert.ToDouble(mystring)));
table.AddCell(TheCell);
Total += Convert.ToDouble(mystring);
break;
case "Tax":
mystring = ((Label)myGrid.Rows[i].Cells[c].Controls[1]).Text.Replace(" €", "");
TheCell = GetCell(2, 1, "F", String.Format(fCUR, Convert.ToDouble(mystring)), "{0}", vCenter, vTop).SetBorder(null);
TheCell.SetNextRenderer(new SubtotalHandlerAwareCellRenderer(TheCell, handlerTotals, "O", Convert.ToDouble(mystring)));
table.AddCell(TheCell);
TotalTax += Convert.ToDouble(mystring);
break;
case "Tax_Credit":
mystring = ((Label)myGrid.Rows[i].Cells[c].Controls[1]).Text.Replace(" €", "");
TheCell = GetCell(2, 1, "F", String.Format(fCUR, Convert.ToDouble(mystring)), "{0}", vCenter, vTop).SetBorder(null);
TheCell.SetNextRenderer(new SubtotalHandlerAwareCellRenderer(TheCell, handlerTotals, "Tax_Credit", Convert.ToDouble(mystring)));
table.AddCell(TheCell);
TotalTax_Credit += Convert.ToDouble(mystring);
break;
default:
break;
}
}
HeightTable = GetHeightTable(table, document) - HeightHeader - HeightTableParz;
}
//START WRITING TOTALS
table.AddCell(GetCell(12, 1, "F", "Total", "{0}", vCenter, vTop).SetBorder(null));
table.AddCell(GetCell(2, 1, "F", String.Format(fCUR, Total), "{0}", vCenter, vTop).SetBorder(null));
table.AddCell(GetCell(2, 1, "F", String.Format(fCUR, TotalTax), "{0}", vCenter, vTop).SetBorder(null));
table.AddCell(GetCell(2, 1, "F", String.Format(fCUR, TotalTax_Credit), "{0}", vCenter, vTop).SetBorder(null));
//END WRITING TOTALS
BordersCells(table, "ROW","V");
BordersCells(table, "HEADER", "V");
document.Add(table);
footerHandler.WriteTotal(pdf);
document.Close();
byte[] content=null;
if (TipoOutput == "RESPONSE")
{
response.ContentType = varJSON.PDF_ContentType;
response.AddHeader("content-disposition", "attachment;filename=" + FileToSave);
response.Cache.SetCacheability(HttpCacheability.NoCache);
response.Outputms.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
}
else
{
content = ms.ToArray();
}
return content;
}
private iText.Layout.Element.Table MakeTable(int columns_numbers, PdfDocument pdf, Document doc,string ID, string Name)
{
iText.Layout.Element.Table table;
table = new iText.Layout.Element.Table(UnitValue.CreatePercentArray(columns_numbers));
table.SetWidth(MillimetersToPoints(250));
table.SetBorder(null);
table.SetBorderBottom(new SolidBorder(0.5f));
table.SetBorderTop(new SolidBorder(0.5f));
table.SetBorderLeft(new SolidBorder(0.5f));
return table;
}
private void MakeTableHeader(GridView dgv, iText.Layout.Element.Table table)
{
int dgvrowcount = dgv.Rows.Count;
int dgvcolumncount = dgv.Columns.Count;
TextAlignment vCenter = TextAlignment.CENTER;
VerticalAlignment vTop = VerticalAlignment.TOP;
// Print The DGV Header To Table Header
for (int i = 0; i < dgvcolumncount; i++)
{
switch (dgv.Columns[i].HeaderText)
{
case "ID":
case "Year Pag.":
case "Year Rif.":
case "Cause":
table.AddHeaderCell(GetCell(1, 1, "V", dgv.Columns[i].HeaderText, "{0}", vCenter, vTop).SetBorderBottom(new SolidBorder(0.5f)));
if (dgv.Columns[i].HeaderText == "ID")
{
table.AddHeaderCell(GetCell(3, 1, "V", "Name", "{0}", vCenter, vTop).SetBorderBottom(new SolidBorder(0.5f)));
}
break;
case "Desc.":
table.AddHeaderCell(GetCell(5, 1, "V", dgv.Columns[i].HeaderText, "{0}", vCenter, vTop).SetBorderBottom(new SolidBorder(0.5f)));
break;
case "Amount":
case "Tax":
case "Tax_Credit":
table.AddHeaderCell(GetCell(2, 1, "V", dgv.Columns[i].HeaderText, "{0}", vCenter, vTop).SetBorderBottom(new SolidBorder(0.5f)));
break;
default:
break;
}
}
}
private float GetHeightTable(iText.Layout.Element.Table TableDati,Document doc)
{
IRenderer pRenderer = TableDati.CreateRendererSubTree().SetParent(doc.GetRenderer());
LayoutResult pLayoutResult = pRenderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
return pLayoutResult.GetOccupiedArea().GetBBox().GetHeight();
}
private void BordersCells(iText.Layout.Element.Table Table, string Tipo, string BordoSuUltima)
{
int rows_number =0;
int columns_number = 0;
bool lastrow = false;
Cell mycell;
switch (Tipo)
{ case "HEADER":
rows_number = Table.GetHeader().GetNumberOfRows();
columns_number = Table.GetHeader().GetNumberOfColumns();
break;
case "ROW":
rows_number = Table.GetNumberOfRows();
columns_number = Table.GetNumberOfColumns();
break;
case "FOOTER":
if (Table.GetFooter() !=null)
{rows_number = Table.GetFooter().GetNumberOfRows();
columns_number = Table.GetFooter().GetNumberOfColumns();}
break;
default:
rows_number = Table.GetNumberOfRows();
columns_number = Table.GetNumberOfColumns();
break;
}
for (int irow = 0; irow < rows_number; irow++)
{
for (int icol = 0; icol < columns_number; icol++)
{
try
{
switch (Tipo)
{ case "HEADER":
mycell = Table.GetHeader().GetCell(irow, icol);
mycell.SetBorderBottom(new SolidBorder(0.5f));
break;
case "ROW":
mycell = Table.GetCell(irow,icol);
if (irow + 1 == rows_number) { lastrow = true; }
if (irow == 0) { mycell.SetBorderTop(new SolidBorder(0.5f)); }
break;
case "FOOTER":
mycell = Table.GetFooter().GetCell(irow, icol);
mycell.SetBorderBottom(new SolidBorder(0.5f));
break;
default:
mycell = Table.GetCell(irow, icol);
break;
}
mycell.SetBorderRight(new SolidBorder(0.5f));
mycell.SetBorderLeft(new SolidBorder(0.5f));
if (mycell.GetColspan() == 12 || (lastrow == true && BordoSuUltima =="V"))
{mycell.SetBorderTop(new SolidBorder(0.5f));}
}
catch (NullReferenceException)
{
}
}
}
}
private static float MillimetersToPoints(float value)
{
return (value / 25.4f) * 72f;
}
private static Cell GetCell(int cm, int rowspan,string ItsHeader, string MyText, string myformat, TextAlignment AllineaMyText, VerticalAlignment AllineaVert)
{
Cell cell = new Cell(rowspan, cm);
Paragraph p;
if (ItsHeader == "V")
{cell.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.LIGHT_GRAY);
cell.SetTextAlignment(AllineaMyText);
p = new Paragraph(String.Format(myformat, MyText)).SetFontSize(10);
cell.SetBorderBottom(new SolidBorder(0.7f));
cell.Add(p);
}
else
{
if (AllineaVert == VerticalAlignment.MIDDLE)
{
Div d = new Div();
d.SetVerticalAlignment(VerticalAlignment.MIDDLE);
p = new Paragraph(String.Format(myformat, MyText)).SetFontSize(8);
p.SetTextAlignment(AllineaMyText);
d.Add(p);
cell.Add(d);
}
else {
cell.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.WHITE);
p = new Paragraph(String.Format(myformat, MyText)).SetFontSize(8);
p.SetTextAlignment(AllineaMyText);
p.SetMultipliedLeading(1.5f);
p.SetMarginTop(0);
cell.Add(p);
}
}
return cell;
private class TableHeaderEventHandler : IEventHandler
{
private iText.Layout.Element.Table table;
private iText.Layout.Element.Table TableDati;
private TableRenderer rendererDati;
private float tableHeight;
private Document doc;
private string name;
public TableHeaderEventHandler(iText.Layout.Element.Table tableDati, Document doc, string ID, string Name)
{
this.doc = doc;
this.name = Name;
this.TableDati = tableDati;
InitTable(ID,Name);
PrintPDFNew.vName = Name;
TableRenderer renderer = (TableRenderer)table.CreateRendererSubTree();
renderer.SetParent(new DocumentRenderer(doc));
this.rendererDati = (TableRenderer)TableDati.CreateRendererSubTree();
this.rendererDati.SetParent(new DocumentRenderer(doc));
LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
tableHeight = result.GetOccupiedArea().GetBBox().GetHeight();
}
public void HandleEvent(Event currentEvent)
{
PdfDocumentEvent docEvent = (PdfDocumentEvent)currentEvent;
PdfDocument pdfDoc = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNum = pdfDoc.GetPageNumber(page);
PdfCanvas canvas = new PdfCanvas(page.NewContentmsBefore(), page.GetResources(), pdfDoc);
PageSize pageSize = pdfDoc.GetDefaultPageSize();
float coordX = pageSize.GetX() + doc.GetLeftMargin();
float coordY = pageSize.GetTop() - doc.GetTopMargin();
float width = pageSize.GetWidth() - doc.GetRightMargin() - doc.GetLeftMargin();
float height = GetTableHeight();
Rectangle rect = new Rectangle(coordX, coordY, width, height);
IRenderer pRenderer = TableDati.CreateRendererSubTree().SetParent(doc.GetRenderer());
LayoutResult pLayoutResult = pRenderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
float y = pLayoutResult.GetOccupiedArea().GetBBox().GetY();
float x = pLayoutResult.GetOccupiedArea().GetBBox().GetX();
float xBottom = pLayoutResult.GetOccupiedArea().GetBBox().GetBottom();
float xHeight = pLayoutResult.GetOccupiedArea().GetBBox().GetHeight();
int x2 = pLayoutResult.GetOccupiedArea().GetPageNumber();
Rectangle pagesize = page.GetPageSizeWithRotation();
float HPage = pagesize.GetHeight();
new Canvas(canvas, rect).Add(table).Close();
}
public float GetTableHeight()
{
return tableHeight;
}
private void InitTable(string ID, string Name)
{
table = new iText.Layout.Element.Table(UnitValue.CreatePercentArray(new float[] { 33, 33, 33 })).UseAllAvailableWidth();
table.SetMarginBottom(5);
table.SetMarginTop(5);
table.SetBorder(Border.NO_BORDER);
Cell cell = new Cell(1, 1).SetBorder(null);
ImageData imageData = ImageDataFactory.Create(PrintPDFNew.PathImmagine);
iText.Layout.Element.Image pdfImg = new iText.Layout.Element.Image(imageData).ScaleAbsolute(Int32.Parse(PrintPDFNew.varJSON.LOGO_LARGHEZZA), Int32.Parse(PrintPDFNew.varJSON.LOGO_Height));
cell.Add(pdfImg);
table.AddCell(cell);
cell = new Cell(1, 1).SetBorder(null);
cell.Add(new Paragraph(PrintPDFNew.varJSON.TITLE).SetFontSize(10).SetTextAlignment(TextAlignment.CENTER));
table.AddCell(cell);
cell = new Cell(1, 1).SetBorder(null);
cell.Add(new Paragraph(ID + ' ' + Name).SetFontSize(10).SetTextAlignment(TextAlignment.RIGHT));
table.AddCell(cell);
cell = new Cell(1, 1).SetBorder(null);
cell.Add(new Paragraph(PrintPDFNew.varJSON.Office1).SetFontSize(10).SetTextAlignment(TextAlignment.LEFT));
table.AddCell(cell);
table.AddCell(new Cell(1, 1).SetBorder(null).Add(new Paragraph("")));
cell = new Cell(1, 1).SetBorder(null);
cell.Add(new Paragraph("Period " + PrintPDFNew.parametersReceveid.Period1 + " " + PrintPDFNew.parametersReceveid.Period2 + " - Competence").SetFontSize(10).SetTextAlignment(TextAlignment.RIGHT));
table.AddCell(cell);
}
}
private class TableFooterEventHandler : IEventHandler
{
private iText.Layout.Element.Table table;
private Document doc;
private float tableHeight;
public TableFooterEventHandler(iText.Layout.Element.Table table, Document doc, string ID, string Name)
{
this.table = table;
this.doc = doc;
}
public void HandleEvent(Event currentEvent)
{
PdfDocumentEvent docEvent = (PdfDocumentEvent)currentEvent;
PdfDocument pdfDoc = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNumber = pdfDoc.GetPageNumber(page);
Rectangle pageSize = page.GetPageSize();
TableRenderer renderer = (TableRenderer)table.CreateRendererSubTree();
renderer.SetParent(new DocumentRenderer(doc));
// Simulate the positioning of the renderer to find out how much space the header table will occupy.
LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
tableHeight = result.GetOccupiedArea().GetBBox().GetHeight();
}
}
protected class Footer : IEventHandler
{
protected PdfFormXObject placeholder;
protected float side = 20;
protected float x = 800;
protected float y = 25;
protected float space = 4.5f;
protected float descent = 3;
public Footer()
{
placeholder = new PdfFormXObject(new Rectangle(0, 0, side, side));
}
public virtual void HandleEvent(Event #event)
{
PdfDocumentEvent docEvent = (PdfDocumentEvent)#event;
PdfDocument pdf = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNumber = pdf.GetPageNumber(page);
Rectangle pageSize = page.GetPageSize();
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, pageSize);
canvas.SetFontSize(9);
Paragraph p = new Paragraph()
.Add("Page ")
.Add(pageNumber.ToString())
.Add(" di");
canvas.ShowTextAligned(p, x, y, TextAlignment.RIGHT);
canvas.Close();
pdfCanvas.AddXObjectAt(placeholder, x + space, y - descent);
pdfCanvas.Release();
}
public void WriteTotal(PdfDocument pdfDoc)
{
Canvas canvas = new Canvas(placeholder, pdfDoc);
canvas.SetFontSize(9);
canvas.ShowTextAligned(pdfDoc.GetNumberOfPages().ToString(),
0, descent, TextAlignment.LEFT);
canvas.Close();
}
}
private class SubtotalHandler
{
private double subtotalSum;
private double subtotalTax;
private double subTotalsTax_Credit;
public virtual void reset(string myField)
{
switch (myField)
{
case "I":
subtotalSum = 0; break;
case "O":
subtotalTax = 0; break;
case "Tax_Credit":
subTotalsTax_Credit = 0; break;
default:
break;
}
}
public virtual void add(string myField, double val)
{
switch (myField)
{
case "I":
subtotalSum += val; break;
case "O":
subtotalTax += val;break;
case "Tax_Credit":
subTotalsTax_Credit += val; break;
default:
break;
}
}
public double get(string myField)
{
switch (myField)
{
case "I":
return subtotalSum;break;
case "O":
return subtotalTax;break;
case "Tax_Credit":
return subTotalsTax_Credit;break;
default:
return 0; break;
}
}
}
private class SubtotalHandlerAwareCellRenderer : CellRenderer
{
private SubtotalHandler subtotalHandler;
private double myValue;
private string myField;
public SubtotalHandlerAwareCellRenderer(Cell modelElement, SubtotalHandler subtotalHandler, string myField, double myValue)
: base(modelElement)
{
this.subtotalHandler = subtotalHandler;
this.myValue = myValue;
this.myField = myField;
}
public override void Draw(DrawContext drawContext)
{
base.Draw(drawContext);
subtotalHandler.add(myField, myValue);
}
public override IRenderer GetNextRenderer()
{
return new SubtotalHandlerAwareCellRenderer((Cell)modelElement, subtotalHandler, myField, myValue);
}
}
private class SubtotalCellRenderer : CellRenderer
{
private SubtotalHandler subtotalHandler;
private double myValue;
private string myField;
public SubtotalCellRenderer(Cell modelElement, SubtotalHandler subtotalHandler,string myField)
: base(modelElement)
{
this.subtotalHandler = subtotalHandler;
this.myField = myField;
}
public override void Draw(DrawContext drawContext)
{
base.Draw(drawContext);
(new Canvas(drawContext.GetCanvas(), drawContext.GetDocument(), occupiedArea.GetBBox())).SetFontSize(8).SetBold().ShowTextAligned(string.Format("{0:#,##0.00}", subtotalHandler.get(myField).ToString()), occupiedArea.GetBBox().GetX() + 38, occupiedArea.GetBBox().GetY() + 3, TextAlignment.CENTER);
subtotalHandler.reset(myField);
}
public override IRenderer GetNextRenderer()
{
return new SubtotalCellRenderer((Cell)modelElement, subtotalHandler,myField);
}
}
}
}
Unable to insert cells into an Open XML document as the OpenXml Excel document. I think the issue is that the cell.Remove() isn't actually clearing cell. I'm unsure because the document says that it has been modified
public static void InsertCell(uint rowIndex, int columnIndex, string value, SheetData sheetData, bool appendRow, EnumValue<CellValues> dataType = null, uint? styleIndex = null)
{
//Row row = null;
// Check if the worksheet contains a row with the specified row index.
var row = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);
if (row == null)
{
row = new Row() { RowIndex = rowIndex };
sheetData.Append(row);
}
// Convert column index to column name for cell reference.
var columnName = GetExcelColumnName(columnIndex);
var cellReference = columnName + rowIndex; // e.g. A1
// Check if the row contains a cell with the specified column name.
var cell = row.Elements<Cell>().FirstOrDefault(c => c.CellReference.Value == cellReference);
//We need to delete the cell if it does exist as the InsertAt function does not delete the existing cell if it has been found
if (cell != null)
{
cell.Remove();
//cell.CellValue.Remove();
}
if (cell == null || cell.CellValue == null)
{
if (dataType == null)
dataType = new EnumValue<CellValues>(CellValues.SharedString);
var newCell = new Cell() { CellReference = cellReference, CellValue = new CellValue(value), DataType = dataType };
if (styleIndex != null)
newCell.StyleIndex = styleIndex;
if (row.ChildElements.Count < columnIndex)
row.AppendChild(newCell);
else
row.InsertAt(newCell, (int)columnIndex);
}
}
Just for reference this is the calling code.
public static string AddToMaterialsRegister(SpreadsheetDocument spreadsheetDocument, com.upvise.client.Query query, JSONObject[] forms)
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
Stylesheet styleSheet = workbookPart.WorkbookStylesPart.Stylesheet;
var stringTable = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
string text = "";
uint currentRow = GetLastUsedRow(sheetData);
for (int i = 0; i < forms.Length; i += 1)
{
long epochDate = forms[i].getLong("date");
epochDate += 10 * 60 * 60 * 1000; //Add 10 hours to get to the QLD timezone
//The date from the form + 1970
epochDate = (epochDate / 1000 / 60 / 60 / 24) + 25569;
JObject customObj = JObject.Parse(forms[i].getString("value"));
string amount = (string)customObj["F4"];
if (!amount.Equals("") && amount != null)
{
switch ((string)customObj["F5"])
{
case "1":
amount += "T";
break;
case "0":
amount += "m3";
break;
}
}
else
amount = "";
// Not important
string tipValue = forms[i].getString("templateid") == "" ? (string)customObj["F18"] : (string)customObj["F19"];
//Grab the photos from the form
var files = query.selectFiles("Forms.forms", forms[i].getString("id") + ":F22");
//int dateIndex = InsertSharedStringItem(epochDate.ToString(), stringTable);
int materialIndex = InsertSharedStringItem((string)customObj["F1"], stringTable);
int amountIndex = InsertSharedStringItem(amount, stringTable);
int deliveredIndex = InsertSharedStringItem((string)customObj["F6"] + " " + (tipValue != null ? tipValue : ""), stringTable);
int certIndex = InsertSharedStringItem(files.Length > 0 ? "Y" : "", stringTable);
int formNameIndex = InsertSharedStringItem(forms[i].getString("name"), stringTable);
InsertCell(currentRow, 1, epochDate.ToString(), sheetData, false, new EnumValue<CellValues>(CellValues.Number), 2);
InsertCell(currentRow, 2, materialIndex.ToString(), sheetData, false, new EnumValue<CellValues>(CellValues.SharedString), 3);
InsertCell(currentRow, 3, amountIndex.ToString(), sheetData, false, new EnumValue<CellValues>(CellValues.SharedString), 3);
InsertCell(currentRow, 4, deliveredIndex.ToString(), sheetData, false, new EnumValue<CellValues>(CellValues.SharedString), 4);
InsertCell(currentRow, 5, certIndex.ToString(), sheetData, false, new EnumValue<CellValues>(CellValues.SharedString), 4);;
InsertCell(currentRow, 6, formNameIndex.ToString(), sheetData, true, new EnumValue<CellValues>(CellValues.SharedString), 4);
currentRow += 1;
}
//spreadsheetDocument.Save();
//spreadsheetDocument.Close();
//worksheetPart.Worksheet.Save();
//workbookPart.Workbook.Save();
return forms.Length + " forms were added";
}
When I run the code it does not add rows to the xlsx.
Any help would be greatly appreciated.
I commented out the Row row = null; as that has wiping the row every time I inserted a new cell.
I am trying to insert data to multiple sheets. For my excel, I have two sheets which are "charts" and "ChartData". I'm able to update the data in sheet2, chartdata sheet, but I'm unable to insert data to sheet1. Here is code which I have tried to insert data into excel sheets. Here data is coming from database.
double ticks = DateTime.Now.Ticks;
// MarketAnalysis ms = new MarketAnalysis();
//ms.Marketanalysis();
File.Copy(Srcpath, #"E:\Works\OpenXML\DownloadTemplates\ExcelGenerated" + ticks + ".xlsx", true);
using (SpreadsheetDocument myworkbok = SpreadsheetDocument.Open(#"E:\Works\OpenXML\DownloadTemplates\ExcelGenerated" + ticks + ".xlsx", true))
{
//Acess the main workbook which contain all the references
WorkbookPart workbookpart = myworkbok.WorkbookPart;
//Get sheet by name
Sheet sheet = workbookpart.Workbook.Descendants<Sheet>().Where(s => s.Name == "ChartData").FirstOrDefault();
//Worksheet Part by ID
WorksheetPart worksheetpart = workbookpart.GetPartById(sheet.Id) as WorksheetPart;
//Sheet data contains all the data
SheetData sheetdata = worksheetpart.Worksheet.GetFirstChild<SheetData>();
DataSet ds = db.Chart1Data();
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
// if (ds.Tables[0].Rows !=DBNull)
//{
string Rowlabel = ds.Tables[0].Rows[i][0].ToString();
// float? FY13Actuval = Convert.ToInt32(ds.Tables[0].Rows[i][1]);
if (!string.IsNullOrEmpty(ds.Tables[0].Rows[i][1].ToString()))
{
// string s = ds.Tables[0].Rows[i][1].ToString();
//FY13Actuval=float.Parse(ds.Tables[0].Rows[i][1].ToString());
FY13Actuval = Convert.ToDouble(ds.Tables[0].Rows[i][1].ToString());
}
else
{
FY13Actuval = null;
}
double? Budget = Convert.ToDouble(ds.Tables[0].Rows[i][2].ToString());
double? Actuval = Convert.ToDouble(ds.Tables[0].Rows[i][3].ToString());
Row contentrow = CreateContentRow(index, Product, Actual, Budget, Forecast);
index++;
sheetdata.AppendChild(contentrow);
// }
}
.......Same code for the other 3 charts
Sheet sheet1 = workbookpart.Workbook.Descendants<Sheet>().Where(s => s.Name == "Charts").FirstOrDefault();
WorksheetPart worksheetpart1 = workbookpart.GetPartById(sheet1.Id) as WorksheetPart;
//Sheet data contains all the data
SheetData sheetdata1 = worksheetpart1.Worksheet.GetFirstChild<SheetData>();
DataSet dsTbl = db.Table();
int SCMTblIndex=5;
for (int i = 0; i < dsTbl.Tables[0].Rows.Count; i++)
{
Row tblRow = CreateScorecardMetricTblRow(SCMTblIndex, dsTbl.Tables[0].Rows[i][0].ToString(),
dsTbl.Tables[0].Rows[i][1].ToString(),
dsTbl.Tables[0].Rows[i][2].ToString());
SCMTblIndex++;
sheetdata1.AppendChild(tblRow);
}
myworkbok.WorkbookPart.Workbook.Save();
}
and the Methods to create the cells:
public static string[] headerColumns = new string[]{ "A", "B", "C", "D", "E", "F", "G", "I", "J" };
public static string[] header = new string[] { "D", "E", "F" };
private static Row CreateContentRow(int index, string Product, double? Actual, double? Budget, double? Forecast)
{
//Create New ROw
Row r = new Row();
r.RowIndex = (UInt32)index;
//Begin colums
Cell c0 = new Cell();
c0.CellReference = headerColumns[0] + index;
CellValue v0 = new CellValue();
v0.Text = Product;
c0.AppendChild(v0);
r.AppendChild(c0);
Cell c1 = new Cell();
c1.CellReference = headerColumns[1] + index;
CellValue v1 = new CellValue();
v1.Text = Actual.ToString();
c1.AppendChild(v1);
r.AppendChild(c1);
Cell c2 = new Cell();
c2.CellReference = headerColumns[2] + index;
CellValue v2 = new CellValue();
v2.Text = Budget.ToString();
c2.AppendChild(v2);
r.AppendChild(c2);
Cell c3 = new Cell();
c3.CellReference = headerColumns[3] + index;
CellValue v3 = new CellValue();
v3.Text = Forecast.ToString();
c3.AppendChild(v3);
r.AppendChild(c3);
return r;
}
public static Row CreateScorecardMetricTblRow(int index, string Act_Data, string Bud_Data, string VarPr_Data)
{
Row r = new Row();
r.RowIndex = (UInt32)index;
//Begin Colums
Cell c0 = new Cell();
c0.CellReference = header[0] + index;
CellValue v0 = new CellValue();
v0.Text = Act_Data;
c0.AppendChild(v0);
r.AppendChild(c0);
Cell c1 = new Cell();
c1.CellReference = header[1] + index;
CellValue v1 = new CellValue();
v1.Text = Bud_Data;
c1.AppendChild(v1);
r.AppendChild(c1);
Cell c2 = new Cell();
c2.CellReference = header[2] + index;
CellValue v2 = new CellValue();
v2.Text = VarPr_Data;
c2.AppendChild(v2);
r.AppendChild(c2);
return r;
}
for multiple sheets to updated just
// Open the document for editing.
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true))
{
// Insert code here.
}
create a two classes for two sheets which you need to update sheet cell values.For each class constructor pass the SpreadsheetDocument object and implement insert text into a cell in a spreadsheet document.Just avoid the code for insertion of new sheet and try the insertion of the cell code only.
You can try this method.....it may be helpful..
private static Cell InsertCellInWorksheet(string columnName, int rowIndex, WorksheetPart worksheetPart)
{
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
string cellReference = columnName + rowIndex;
Alignment alignment1 = new Alignment() { WrapText = true };
// If the worksheet does not contain a row with the specified row index, insert one.
Row row;
row = new Row() { RowIndex = 3, StyleIndex = 1 };
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 = Convert.ToUInt32(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)
{
Row row2;
row2 = new Row() { RowIndex = 3, StyleIndex = 1 };
Cell rCell = null;
foreach (Cell celld in row.Elements<Cell>())
{
if (string.Compare(celld.CellReference.Value, "A3", true) > 0)
{
rCell = celld;
break;
}
}
// Add the cell to the cell table at A1.
Cell newCell = new Cell() { CellReference = "C3" };
//Cell newCell1 = new Cell() { CellReference = "D3" };
row.InsertBefore(newCell, rCell);
//row.InsertBefore(newCell1, rCell);
// Set the cell value to be a numeric value of 100.
newCell.CellValue = new CellValue("#GUIDeXactLCMS#");
//newCell1.CellValue = new CellValue("EN");
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
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)
{
//string val = cell.CellReference.Value;
refCell = cell;
break;
}
}
Cell newCell = new Cell() { CellReference = cellReference };
row.InsertBefore(newCell, refCell);
return newCell;
}
worksheet.Save();
}
I'm using the following code to convert an Excel to a datatable using EPPlus:
public DataTable ExcelToDataTable(string path)
{
var pck = new OfficeOpenXml.ExcelPackage();
pck.Load(File.OpenRead(path));
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
bool hasHeader = true;
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
var row = tbl.NewRow();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
tbl.Rows.Add(row);
}
pck.Dispose();
return tbl;
}
It creates the Excel, however, when I try to open it, it gives me the message that it is locked for editing by another user and that I can only open it in Read-Only mode.
I thought using:
pck.Dispose();
would solve the issue, however I'm still getting the same error.
Also, when I try to delete the file, I get the message: The action can't be completed because the file is open in WebDev.WebServer40.EXE.
Any ideas how to resolve this?
Thanks in advance. :)
I see, that's what i've posted recently here(now corrected). It can be improved since the ExcelPackage and the FileStream(from File.OpenRead) are not disposed after using.
public static DataTable GetDataTableFromExcel(string path, bool hasHeader = true)
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
for (int rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
DataRow row = tbl.Rows.Add();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
}
return tbl;
}
}
A extension version of Tim Schmelter's answer.
public static DataTable ToDataTable(this ExcelWorksheet ws, bool hasHeaderRow = true)
{
var tbl = new DataTable();
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
tbl.Columns.Add(hasHeaderRow ?
firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
var startRow = hasHeaderRow ? 2 : 1;
for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
var row = tbl.NewRow();
foreach (var cell in wsRow) row[cell.Start.Column - 1] = cell.Text;
tbl.Rows.Add(row);
}
return tbl;
}
I've created a method that converts an Excel file to a DataTable using EPPlus, and tried to maintain Type Safety. Also duplicate column names are handled and with a boolean you can tell the method wether the sheet has a row with headers. I've created it for a complex import process that has several steps after uploading that requires user input before committing to the database.
private DataTable ExcelToDataTable(byte[] excelDocumentAsBytes, bool hasHeaderRow)
{
DataTable dt = new DataTable();
string errorMessages = "";
//create a new Excel package in a memorystream
using (MemoryStream stream = new MemoryStream(excelDocumentAsBytes))
using (ExcelPackage excelPackage = new ExcelPackage(stream))
{
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
//check if the worksheet is completely empty
if (worksheet.Dimension == null)
{
return dt;
}
//add the columns to the datatable
for (int j = worksheet.Dimension.Start.Column; j <= worksheet.Dimension.End.Column; j++)
{
string columnName = "Column " + j;
var excelCell = worksheet.Cells[1, j].Value;
if (excelCell != null)
{
var excelCellDataType = excelCell;
//if there is a headerrow, set the next cell for the datatype and set the column name
if (hasHeaderRow == true)
{
excelCellDataType = worksheet.Cells[2, j].Value;
columnName = excelCell.ToString();
//check if the column name already exists in the datatable, if so make a unique name
if (dt.Columns.Contains(columnName) == true)
{
columnName = columnName + "_" + j;
}
}
//try to determine the datatype for the column (by looking at the next column if there is a header row)
if (excelCellDataType is DateTime)
{
dt.Columns.Add(columnName, typeof(DateTime));
}
else if (excelCellDataType is Boolean)
{
dt.Columns.Add(columnName, typeof(Boolean));
}
else if (excelCellDataType is Double)
{
//determine if the value is a decimal or int by looking for a decimal separator
//not the cleanest of solutions but it works since excel always gives a double
if (excelCellDataType.ToString().Contains(".") || excelCellDataType.ToString().Contains(","))
{
dt.Columns.Add(columnName, typeof(Decimal));
}
else
{
dt.Columns.Add(columnName, typeof(Int64));
}
}
else
{
dt.Columns.Add(columnName, typeof(String));
}
}
else
{
dt.Columns.Add(columnName, typeof(String));
}
}
//start adding data the datatable here by looping all rows and columns
for (int i = worksheet.Dimension.Start.Row + Convert.ToInt32(hasHeaderRow); i <= worksheet.Dimension.End.Row; i++)
{
//create a new datatable row
DataRow row = dt.NewRow();
//loop all columns
for (int j = worksheet.Dimension.Start.Column; j <= worksheet.Dimension.End.Column; j++)
{
var excelCell = worksheet.Cells[i, j].Value;
//add cell value to the datatable
if (excelCell != null)
{
try
{
row[j - 1] = excelCell;
}
catch
{
errorMessages += "Row " + (i - 1) + ", Column " + j + ". Invalid " + dt.Columns[j - 1].DataType.ToString().Replace("System.", "") + " value: " + excelCell.ToString() + "<br>";
}
}
}
//add the new row to the datatable
dt.Rows.Add(row);
}
}
//show error messages if needed
Label1.Text = errorMessages;
return dt;
}
The webforms button click for demo purposes.
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
DataTable dt = ExcelToDataTable(FileUpload1.FileBytes, CheckBox1.Checked);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
VDWWD's answer above works great to keep type safety, and I built upon it with some improvements.
Method reads from a file directly.
Column type detection by using all rows and not just one value. Column type is set to String if more than type is found in the column.
Error Messages returned in a list of strings.
Here is the updated version:
public static DataTable ExcelToDataTable(string path, ref List<string> errorList, bool hasHeaderRow = true )
{
DataTable dt = new DataTable();
errorList = new List<string>();
//create a new Excel package
using (ExcelPackage excelPackage = new ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
excelPackage.Load(stream);
}
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
//check if the worksheet is completely empty
if (worksheet.Dimension == null)
{
return dt;
}
//add the columns to the datatable
for (int j = worksheet.Dimension.Start.Column; j <= worksheet.Dimension.End.Column; j++)
{
string columnName = "Column " + j;
//Build hashset with all types in the row
var columnTypes = new HashSet<Type>();
for (int i = worksheet.Dimension.Start.Row + Convert.ToInt32(hasHeaderRow); i <= worksheet.Dimension.End.Row; i++)
{
//Only add type if cell value not empty
if (worksheet.Cells[i, j].Value != null)
{
columnTypes.Add(worksheet.Cells[i, j].Value.GetType());
}
}
var excelCell = worksheet.Cells[1, j].Value;
if (excelCell != null)
{
Type excelCellDataType = null;
//if there is a headerrow, set the next cell for the datatype and set the column name
if (hasHeaderRow == true)
{
columnName = excelCell.ToString();
//check if the column name already exists in the datatable, if so make a unique name
if (dt.Columns.Contains(columnName) == true)
{
columnName = columnName + "_" + j;
}
}
//Select input type for the column
if (columnTypes.Count == 1)
{
excelCellDataType = columnTypes.First();
}
else
{
excelCellDataType = typeof(string);
}
//try to determine the datatype for the column (by looking at the next column if there is a header row)
if (excelCellDataType == typeof(DateTime))
{
dt.Columns.Add(columnName, typeof(DateTime));
}
else if (excelCellDataType == typeof(Boolean))
{
dt.Columns.Add(columnName, typeof(Boolean));
}
else if (excelCellDataType == typeof(Double))
{
//determine if the value is a decimal or int by looking for a decimal separator
//not the cleanest of solutions but it works since excel always gives a double
if (excelCellDataType.ToString().Contains(".") || excelCellDataType.ToString().Contains(","))
{
dt.Columns.Add(columnName, typeof(Decimal));
}
else
{
dt.Columns.Add(columnName, typeof(Int64));
}
}
else
{
dt.Columns.Add(columnName, typeof(String));
}
}
else
{
dt.Columns.Add(columnName, typeof(String));
}
}
//start adding data the datatable here by looping all rows and columns
for (int i = worksheet.Dimension.Start.Row + Convert.ToInt32(hasHeaderRow); i <= worksheet.Dimension.End.Row; i++)
{
//create a new datatable row
DataRow row = dt.NewRow();
//loop all columns
for (int j = worksheet.Dimension.Start.Column; j <= worksheet.Dimension.End.Column; j++)
{
var excelCell = worksheet.Cells[i, j].Value;
//add cell value to the datatable
if (excelCell != null)
{
try
{
row[j - 1] = excelCell;
}
catch
{
errorList.Add("Row " + (i - 1) + ", Column " + j + ". Invalid " + dt.Columns[j - 1].DataType.ToString().Replace("System.", "") + " value: " + excelCell.ToString() );
}
}
}
//add the new row to the datatable
dt.Rows.Add(row);
}
}
return dt;
}
This is an improvement to the generic one above. Use is if you have a class with the following properties, "Name", "Surname", "Telephone", "Fax" and you have a excel sheet with the first row with the same names, it will load the excel rows into a class object and pop it into a List
public static List<T> GetClassFromExcel<T>(string path, int fromRow, int fromColumn, int toRow = 0, int toColumn = 0)
{
if (toColumn != 0 && toColumn < fromColumn) throw new Exception("toColumn can not be less than fromColumn");
if (toRow != 0 && toRow < fromRow) throw new Exception("toRow can not be less than fromRow");
List<T> retList = new List<T>();
using (var pck = new ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
//Retrieve first Worksheet
var ws = pck.Workbook.Worksheets.First();
//If the to column is empty or 0, then make the tocolumn to the count of the properties
//Of the class object inserted
toColumn = toColumn == 0 ? typeof(T).GetProperties().Count() : toColumn;
//Read the first Row for the column names and place into a list so that
//it can be used as reference to properties
Dictionary<string, int> columnNames = new Dictionary<string, int>();
// wsRow = ws.Row(0);
var colPosition = 0;
foreach (var cell in ws.Cells[1, 1, 1, toColumn == 0 ? ws.Dimension.Columns : toColumn])
{
columnNames.Add(cell.Value.ToString(), colPosition);
colPosition++;
}
//create a instance of T
T objT = Activator.CreateInstance<T>();
//Retrieve the type of T
Type myType = typeof(T);
//Get all the properties associated with T
PropertyInfo[] myProp = myType.GetProperties();
//Loop through the rows of the excel sheet
for (var rowNum = fromRow; rowNum <= (toRow == 0? ws.Dimension.End.Row : toRow); rowNum++)
{
var wsRow = ws.Cells[rowNum, fromColumn, rowNum, ws.Cells.Count()];
foreach (var propertyInfo in myProp)
{
if (columnNames.ContainsKey(propertyInfo.Name))
{
int position = 0;
columnNames.TryGetValue(propertyInfo.Name, out position);
//int position = columnNames.IndexOf(propertyInfo.Name);
//To prevent an exception cast the value to the type of the property.
propertyInfo.SetValue(objT, Convert.ChangeType(wsRow[rowNum, position + 1].Value, propertyInfo.PropertyType));
}
}
retList.Add(objT);
}
}
return retList;
}
now you can use the list as a databinding source if you need...
A give from me to you... :) Daniel C. Vrey
Updated it for toColumn to work and added toRow and followed Andreas suggestions. Thumbs up for Andreas
public static List<T> getClassFromExcel<T>(string path, int fromRow, int fromColumn, int toColumn = 0) where T : class
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
List<T> retList = new List<T>();
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets.First();
toColumn = toColumn == 0 ? typeof(T).GetProperties().Count() : toColumn;
for (var rowNum = fromRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
T objT = Activator.CreateInstance<T>();
Type myType = typeof(T);
PropertyInfo[] myProp = myType.GetProperties();
var wsRow = ws.Cells[rowNum, fromColumn, rowNum, toColumn];
for (int i = 0; i < myProp.Count(); i++)
{
myProp[i].SetValue(objT, wsRow[rowNum, fromColumn + i].Text);
}
retList.Add(objT);
}
return retList;
}
}
public static List<T> GetClassFromExcel<T>(string path, int fromRow, int fromColumn, int toRow = 0, int toColumn = 0) where T: class, new()
{
if (toColumn != 0 && toColumn < fromColumn) throw new Exception("toColumn can not be less than fromColumn");
if (toRow != 0 && toRow < fromRow) throw new Exception("toRow can not be less than fromRow");
List<T> retList = new List<T>();
using (var pck = new ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
//Retrieve first Worksheet
var ws = pck.Workbook.Worksheets.First();
toColumn = toColumn == 0 ? typeof(T).GetProperties().Count() : toColumn; //If the to column is empty or 0, then make the tocolumn to the count of the properties Of the class object inserted
//Read the first Row for the column names and place into a list so that
//it can be used as reference to properties
Dictionary<string, int> columnNames = new Dictionary<string, int>();
// wsRow = ws.Row(0);
var colPosition = 0;
foreach (var cell in ws.Cells[1, 1, 1, toColumn == 0 ? ws.Dimension.Columns : toColumn])
{
columnNames.Add(cell.Value.ToString(), colPosition);
colPosition++;
}
//Retrieve the type of T
Type myType = typeof(T);
//Get all the properties associated with T
PropertyInfo[] myProp = myType.GetProperties();
//Loop through the rows of the excel sheet
for (var rowNum = fromRow + 1; rowNum <= (toRow == 0 ? ws.Dimension.End.Row : toRow); rowNum++) // fromRow + 1 to read from next row after columnheader
{
//create a instance of T
//T objT = Activator.CreateInstance<T>();
T objT = new T();
// var wsRow = ws.Cells[rowNum, fromColumn, rowNum, ws.Cells.Count()]; //ws.Cells.Count() causing out of range error hence using ws.Dimension.Columns to get last column index
var wsRow = ws.Cells[rowNum, fromColumn, rowNum, ws.Dimension.Columns];
foreach (var propertyInfo in myProp)
{
var attribute = propertyInfo.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
string displayName = attribute != null && !string.IsNullOrEmpty(attribute.DisplayName) ? attribute.DisplayName : propertyInfo.Name; // If DisplayName annotation not used then get property name itself
if (columnNames.ContainsKey(displayName))
{
int position = 0;
columnNames.TryGetValue(displayName, out position);
////int position = columnNames.IndexOf(propertyInfo.Name);
////To prevent an exception cast the value to the type of the property.
propertyInfo.SetValue(objT, Convert.ChangeType(wsRow[rowNum, position + 1].Value, propertyInfo.PropertyType));
}
}
retList.Add(objT);
}
}
return retList;
}
//IMPLEMENTATION DONE BY PLACING Code IT IN SEPARATE Helpers.CS file and
//Consuming it in this manner
List<CustomerExcelModel> records =
Helpers.GetClassFromExcel<CustomerExcelModel>(filelocation, 1, 1);
Thanks a lot to the user who Submitted code and Andreas for suggestion
Here are the Following changes done, i am new to generics so forgive and correct me for any mistakes please find modified code below it might help someone
Added Display Annotation entity model to map with the Excel Column
name so that Column Name with spaces can also be handled.
had issue "T objT " as it was outside of for loop and hence caused
same value repeatedly inserted into List fixed it by
instantiating inside loop i.e using "new T()"
Fixed Column out of range error by using "ws.Dimension.Columns" to get Column count , instead of ws.Cells.Count() as it caused out
range column error
for looping through row data added +1 to it ,as RowNum=1 was reading header name also so done minor change of "rowNum = fromRow + 1"
Here I am sharing how you can read the excel. You can modify it to store each date in datatables.
public void readXLS(string FilePath)
{
FileInfo existingFile = new FileInfo(FilePath);
using (ExcelPackage package = new ExcelPackage(existingFile))
{
//get the first worksheet in the workbook
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int colCount = worksheet.Dimension.End.Column; //get Column Count
int rowCount = worksheet.Dimension.End.Row; //get row count
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
//You can update code here to add each cell value to DataTable.
Console.WriteLine(" Row:" + row + " column:" + col + " Value:" + worksheet.Cells[row, col].Value.ToString().Trim());
}
}
}
}
Reff: http://sforsuresh.in/read-data-excel-sheet-insert-database-table-c/
Use below code if you want to read data of each worksheet from excel, as well if worksheet contain date format data for particular column.
public static DataSet ReadExcelFileToDataSet2(string filePath, bool isFirstRowHeader=true)
{
DataSet result = new DataSet();
Excel.ExcelPackage xlsPackage = new Excel.ExcelPackage(new FileInfo(filePath)); //using Excel = OfficeOpenXml; <--EPPLUS
Excel.ExcelWorkbook workBook = xlsPackage.Workbook;
try
{
for (int count = 1; count <= workBook.Worksheets.Count; count++)
{
Excel.ExcelWorksheet wsworkSheet = workBook.Worksheets[count];
if (wsworkSheet.Name.ToLower() == "sheetName")
{
wsworkSheet.Column(4).Style.Numberformat.Format = "MM-dd-yyyy"; // set column value to read as Date Type or numberformat
}
DataTable tbl = new DataTable();
// wsworkSheet.Dimension - (It will return cell dimesion like A1:N7 , means returning the worksheet dimesions.)
// wsworkSheet.Dimension.End.Address - (It will return right bottom cell like N7)
// wsworkSheet.Dimension.End.Columns - (It will return count from A1 to N7 like here 14)
foreach (var firstRowCell in wsworkSheet.Cells[1, 1, 1, wsworkSheet.Dimension.End.Column]) //.Cells[Row start, Column Start, Row end, Column End]
{
var colName = "";
colName = firstRowCell.Text;
tbl.Columns.Add(isFirstRowHeader ? colName : string.Format("Column {0}", firstRowCell.Start.Column)); //Geth the Column index (index starting with 1) from the left top.
}
var startRow = isFirstRowHeader ? 2 : 1;
for (int rowNum = startRow; rowNum <= wsworkSheet.Dimension.End.Row; rowNum++)
{
var wsRow = wsworkSheet.Cells[rowNum, 1, rowNum, wsworkSheet.Dimension.End.Column]; // wsworkSheet.Cells[Row start, Column Start, Row end, Column End]
DataRow row = tbl.Rows.Add();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
}
tbl.TableName = wsworkSheet.Name;
result.Tables.Add(tbl);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return result;
}