Using OpenXML to insert a datatable into excel - asp.net

I have a datatable that - depending on the user selection - will generate a dynamic datatable with any number of rows and columns. I'm currently using OpenXml to manipulate said spreadsheet. How would I go about inserting a datatable?
Thanks
Stu

I found some code which I was able to modify to suit my needs. Hope someone finds this useful.
public void ExportDataTable(System.Data.DataTable exportData, SheetData sheetData)
{
//add column names to the first row
Row header = new Row();
header.RowIndex = (UInt32)42;
SheetData sheetData2 = new SheetData();
foreach (DataColumn column in exportData.Columns)
{
Cell headerCell = createTextCell(exportData.Columns.IndexOf(column) + 1, Convert.ToInt32(header.RowIndex.Value), column.ColumnName);
header.AppendChild(headerCell);
}
sheetData.AppendChild(header);
//loop through each data row
DataRow contentRow;
int startRow = 43;
for (int i = 0; i < exportData.Rows.Count; i++)
{
contentRow = exportData.Rows[i];
sheetData.AppendChild(createContentRow(contentRow, i + startRow));
}
}
private Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
Cell cell = new Cell();
cell.DataType = CellValues.InlineString;
cell.CellReference = getColumnName(columnIndex) + rowIndex;
InlineString inlineString = new InlineString();
Text t = new Text();
t.Text = cellValue.ToString();
inlineString.AppendChild(t);
cell.AppendChild(inlineString);
return cell;
}
private Row createContentRow(DataRow dataRow, int rowIndex)
{
Row row = new Row
{
RowIndex = (UInt32)rowIndex
};
for (int i = 0; i < dataRow.Table.Columns.Count; i++)
{
Cell dataCell = createTextCell(i + 1, rowIndex, dataRow[i]);
row.AppendChild(dataCell);
}
return row;
}
private string getColumnName(int columnIndex)
{
int dividend = columnIndex;
string columnName = String.Empty;
int modifier;
while (dividend > 0)
{
modifier = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modifier).ToString() + columnName;
dividend = (int)((dividend - modifier) / 26);
}
return columnName;
}

Related

NPOI: Excel column formatted to decimal with SXSSFWorkbook?

I am developing a website with ASP.net (VS2015 C #).
I need to export a MySql table with a large amount of data (500000+ rows and 100 columns) to excel (xlsx), with format.
After trying many options, the NPOI (v 3.20) library allows this export using types that use streaming (SXSSFWorkbook & SXSSFSheet).
If I use XSSFWorkbook I get and Out of memory filling the rows.
With SXSSFWorkbook I have been able to format the xlsx with different fonts and colors, but I am having problems with the types of data exported:
Date types ok
Int types ok
Text ok
Decimals inputs like 100.35 --> problems, I get a text column. I need a ouput like a number 100,35.
The code I use to format the data is:
SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sh = (SXSSFSheet)wb.CreateSheet("Sheet 1");
sh.SetRandomAccessWindowSize(100);
ICellStyle testStyleHeader = wb.CreateCellStyle();
ICellStyle testStyleRow = wb.CreateCellStyle();
// Header Style
testStyleHeader.FillForegroundColor = NPOI.SS.UserModel.IndexedColors.RoyalBlue.Index;
testStyleHeader.FillPattern = FillPattern.SolidForeground;
// Double style (with 2 decimals like 453.65)
ICellStyle cellStyleDouble = wb.CreateCellStyle();
cellStyleDouble.DataFormat = wb.CreateDataFormat().GetFormat("0.00");
// Font
XSSFFont hFontBlack = (XSSFFont)wb.CreateFont();
hFontBlack.FontHeightInPoints = 11;
hFontBlack.FontName = "Calibri";
hFontBlack.Color = NPOI.SS.UserModel.IndexedColors.Black.Index;
testStyleHeader.SetFont(hFontBlack);
IRow row = sh.CreateRow(0);
int j = 0;
ICell cell = row.CreateCell(j);
// Fill Header row
cell.SetCellValue("XXXX"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("YYYY"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("ZZZZ"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("WWWW"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
// Fill Rows
int i = 1; // row Number
IRow row2; // No Header Row
ICell cell2; // No Header cell
while (dr.Read()) // dr is the DataReader
{
row2 = sh.CreateRow(i);
for (int cont = 0; cont < NumColumns; cont++)
{
if (cont == 0) // This column is a date
{
…. // code for date format
}
else if (cont == 3) // Double column with 2 decimals¡! (values samples 100.45 5654.80 etc.)
{
ICell cell3 = row2.CreateCell(j, NPOI.SS.UserModel.CellType.Numeric);
cell3.CellStyle = cellStyleDouble;
cell3.SetCellValue(Convert.ToDouble(dr[cont]));
}
else
{…. // code for tex format, int format etc.
}
}
i++;
}
With this code, in the decimal column (cont ==3), I get a text column.
However, with the same code, if I declare the no streaming types:
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sh = (SSFSheet)wb.CreateSheet("Sheet 1");
Only with this changes I get a perfect numeric columnn 3...
For this line:
cellStyleDouble.DataFormat = wb.CreateDataFormat().GetFormat("0.00");
I have tried with different types:
"#.#"
"#,##0.000"
"##.#"
Etc…
In some cases I get a number, but not with the desired format.
So...streaming types do not allow this formatting?
Just change the Culture Info to en-US
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-Us");
ISheet worksheet = Workbook.CreateSheet(dt.TableName);
IRow HeaderRow = worksheet.CreateRow(0);
for (int i = 0; i < dt.Columns.Count; i++)
{
ICell HeaderCell = HeaderRow.CreateCell(i);
HeaderCell.SetCellValue(dt.Columns[i].ColumnName);
}
for (int j = 0; j < dt.Rows.Count; j++)
{
IRow Row = worksheet.CreateRow(j + 1);
for (int i = 0; i < dt.Columns.Count; i++)
{
ICell Cell = Row.CreateCell(i);
if (dt.Columns[i].DataType.IsOfType(typeof(decimal)) && dt.Rows[j][i] != DBNull.Value)
{
Cell.SetCellType(CellType.Numeric);
Cell.SetCellValue((double)dt.Rows[j][i]);
}
else
Cell.SetCellValue(dt.Rows[j][i].ToString());
}
}
Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-Br");
It works for me!
can you try your formatting based on below code snippet. I am using this approach to format phone number.
XSSFCellStyle currencyCellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat currencyDataFormat = (XSSFDataFormat)workbook.CreateDataFormat();
currrencyCellStyle.SetDataFormat(currencyDataFormat.GetFormat("00000.00")); //Formats: #####.##, 00000##.##
sometimes its tricky to find exact formatting in NPOI :). Please try below approaches
ICellStyle CellStyle = workbook.CreateCellStyle();
CellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("number"); // or Number
or
CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat("#.#")); // or #####.## or number

ASP.NET - Input string was not in a correct format

I am getting an error saying my input string was not in a correct format when I try to get, multiply and display I stored data's in cookies.
It says there was an error in a part in total = total + (Convert.ToInt32(a[2].ToString()) * Convert.ToInt32(a[3].ToString()));
Somebody help me please. Here is my code:
protected void Page_Init(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[7] { new DataColumn("product_name"), new DataColumn("product_desc"), new DataColumn("product_price"), new DataColumn("product_qty"), new DataColumn("product_images"), new DataColumn("id"), new DataColumn("product_id") });
if (Request.Cookies["aa"] != null)
{
s = Convert.ToString(Request.Cookies["aa"].Value);
string[] strArr = s.Split('|');
for (int i = 0; i < strArr.Length; i++)
{
t = Convert.ToString(strArr[i].ToString());
string[] strArr1 = t.Split(',');
for (int j = 0; j < strArr1.Length; j++)
{
a[j] = strArr1[j].ToString();
}`enter code here`
dt.Rows.Add(a[0].ToString(), a[1].ToString(), a[2].ToString(), a[3].ToString(), a[4].ToString(), i.ToString(), a[5].ToString());
total = total + (Convert.ToInt32(a[2].ToString()) * Convert.ToInt32(a[3].ToString()));
totalcount = totalcount + 1;
cart_items.Text = totalcount.ToString();
cart_price.Text = total.ToString();
}
}
I recomment you to use int.TryParse(...) if you want to convert form string.
It could be like this:
int var2, var3 = 0;
if(int.TryParse(a[2].ToString(), out var2)
&& int.TryParse(a[3].ToString(), out var3))
{
total += (var2 * var3);
}

unable to download xlsx file using POI

Hi i working on poi poc to generate xlsx file in webapplication i was able to render excel standalone well but when i integrate codebase in my project i was getting below error.
below is code base base to download xlsx file in webapplication
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet spreadsheet = workbook.createSheet("Sheet1");
XSSFRow row = spreadsheet.createRow(0);
XSSFCell cell;
while (response.nextResultSet()) {
resultSet = response.getResultSet();
Object[] columnMetaData = resultSet.getColumnNames();
int columnCount = columnMetaData.length;
//Columns Loop
ArrayList<String> columns = new ArrayList<String>();
for (int i = 1; i < columnCount; i++) {
String columnName = (String) columnMetaData[i];
columns.add(columnName);
cell = row.createCell(i-1);
cell.setCellValue(columnName);
}
int i=1;
while (resultSet.nextRow()) {
row = spreadsheet.createRow(i);
i++; // counter for each row of data
for (int j = 0; j < columnMetaData.length; j++)
{
String keyVal = String.valueOf(columnMetaData[j]);
String value = (String)resultSet.getValue(keyVal);
cell = row.createCell(j);
cell.setCellValue(value);
}
}
log.info("value if i--->" + i);
for (int k = 1; k < columnCount; k++) {
spreadsheet.autoSizeColumn(k-1);
}
}
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
workbook.write(outByteStream);
context.getResponse().setHeader("content-disposition", "inline;filename=" + calendar.getTimeInMillis() + ".xlsx");
context.getResponse().setContentType("application/Excel");
context.getRequest().setAttribute("called_from", "excel");
//context.getResponse().setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
//context.getResponse().setHeader("Content-Disposition", "attachment; filename=testxls.xlsx");
}
OutputStream os = null;
os = context.getResponse().getOutputStream();
byte [] outArray = is.toByteArray();
context.getResponse().setContentLength(outArray.length);
os.write(outArray);
log.info(os.toString());
os.flush();

Create 2 or more text files with ASP.NET

I have created a web app which creates 1 text file. Inside this text file it is created 1000 rows with the same word "TRY AGAIN". After this each 50 rows I put a random code which means in 1000 rows, 20 rows are random.
This is my code:
static Random randNum = new Random();
public static string Random(int ran)
{
string _charachters = "ABCDEFGHIJKMLNOPQRSTUVWXYZ0123456789";
char[] chars = new char[ran];
int allowedCharCount = _charachters.Length;
for (int i = 0; i < ran; i++)
{
chars[i] = _charachters[(int)((_charachters.Length) * randNum.NextDouble())];
}
return new string(chars);
}
protected void Button1_Click(object sender, EventArgs e)
{
string pathCreate = #"C:\" + TextBox3.Text + ".txt";
if (!File.Exists(pathCreate))
{
using (StreamWriter sw = File.CreateText(pathCreate))
{
for (int i = 1; i <= int.Parse(TextBox1.Text); i++)
{
sw.WriteLine("TRY AGAIN.");
}
}
}
string pathRandom = #"C:\" + TextBox3.Text + ".txt";
string[] lines = File.ReadAllLines(pathRandom);
for (int i = 0; i < lines.Length; i += int.Parse(TextBox2.Text))
{
lines[i] = lines[i].Replace("TRY AGAIN.", Random(int.Parse("7")));
}
File.WriteAllLines(pathRandom, lines);
}
Now I want to create 2 ore more text files with one click of a button. And on each text file there will be random codes (not duplicates). Any idea?
Thank You.
I found the solution. It is late in my country and my brain barely works. :P
for(int j = 1; j <= 10; j++)
{
string pathKrijo = #"C:\inetpub\wwwroot\KODET\" + j.ToString() + ".txt";
using (StreamWriter sw = File.CreateText(pathKrijo))
{
for (int i = 1; i <= 100; i++)
{
sw.WriteLine("Provo Përsëri.");
}
}
string pathKodFitues = #"C:\inetpub\wwwroot\KODET\" + j.ToString() + ".txt";
string[] lines = File.ReadAllLines(pathKodFitues);
for (int i = 0; i < lines.Length; i += 10)
{
lines[i] = lines[i].Replace("Provo Përsëri.", Random(int.Parse("7")));
}
File.WriteAllLines(pathKodFitues, lines);
}

The IListSource does not contain any data sources.during next page is clicked in gridview

Lbl_Username.Text = FirstName + " " + LastName;
if (!IsPostBack)
{
ds = objSun.FetchTravelDetails(userId);
int datasetcount = ds.Tables[0].Rows.Count;
if (datasetcount == 0)
{
dt.Columns.Add("request_ID");
dt.Columns.Add("userId");
dt.Columns.Add("");
dt.Columns.Add("status");
dt.Columns.Add("remark");
dt.Columns.Add("");
for (int i = 0; i < 9; i++)
{
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
}
GridView_RequisitionManagement.DataSource = dt;
GridView_RequisitionManagement.DataBind();
}
else
{
GridView_RequisitionManagement.DataSource = ds;
GridView_RequisitionManagement.DataBind();
}
}
}
protected void GridView_RequisitionManagement_RowDataBound(object sender, GridViewRowEventArgs e)
{
int datasetcount1 = ds.Tables[0].Rows.Count;
if (datasetcount1 != 0)
{
for (int i = 0; i < GridView_RequisitionManagement.Rows.Count; i++)
{
LinkButton lnk_view = new LinkButton();
lnk_view = GridView_RequisitionManagement.Rows[i].FindControl("LinkBtn_ViewFullDetails_GridView_LeaveManagement") as LinkButton;
int type = Convert.ToInt32(ds.Tables[0].Rows[i]["request_Type"].ToString());
string typeName = "";
string requestId = GridView_RequisitionManagement.DataKeys[i][0].ToString();
string request_userId = GridView_RequisitionManagement.DataKeys[i][1].ToString();
switch (type)
{
case 2:
{
typeName = "Travel Request";
lnk_view.PostBackUrl = "Status_ViewDetails_TravelClaims.aspx?requestId=" + requestId;
break;
}
case 3:
{
typeName = "Other Claims";
lnk_view.PostBackUrl = "Status_ViewDetails_OtherClaims.aspx?requestId=" + requestId;
break;
}
case 4:
{
typeName = "Petty cash";
lnk_view.PostBackUrl = "Status_ViewDetails_PettyCashVoucher.aspx?requestId=" + requestId;
break;
}
case 5:
{
typeName = "Advance";
lnk_view.PostBackUrl = "Status_ViewDetails_AdvanceRequisitions.aspx?requestId=" + requestId;
break;
}
}
GridView_RequisitionManagement.Rows[i].Cells[1].Text = Convert.ToDateTime(ds.Tables[0].Rows[i]["date"].ToString()).ToShortDateString();
GridView_RequisitionManagement.Rows[i].Cells[2].Text = typeName;
}
}
else
{
for (int j = 0; j < GridView_RequisitionManagement.Rows.Count; j++)
{
GridViewRow rows = GridView_RequisitionManagement.Rows[j];
LinkButton lnk_grd_views = (LinkButton)rows.FindControl("LinkBtn_ViewFullDetails_GridView_LeaveManagement") as LinkButton;
lnk_grd_views.Visible = false;
}
}
}
protected void GridView_RequisitionManagement_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView_RequisitionManagement.PageIndex = e.NewPageIndex;
GridView_RequisitionManagement.DataSource = ds;
GridView_RequisitionManagement.DataBind();
}
Hi guys, I need some help here. I'm using the above code to display the details
in the GridView. The DataTable and DataSet are used to populate the GridView. Now I want to do paging in the GridView, but when the next page is clicked it shows the following error:
The IListSource does not contain any data sources
and the next page in the grid shows empty.
Please assist me with this.
It seems as though you are only setting the DataSet 'ds' if it isn't a postback. So when the PageIndexChanging event is run ds is not going to be set to a dataset.
Try moving
ds = objSun.FetchTravelDetails(userId);
Above the if(!IsPostback) line.

Resources