GridView to Excel using EPPlus - asp.net

I'm trying to create an excel sheet using the EPPlus's library.
However, the output excel file does not relate well to cells of representing numbers.
The code I'm using is:
using (var pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add(string.IsNullOrEmpty(SpreadsheetName) ? "Report" : SpreadsheetName);
ws.Cells["B2"].LoadFromDataTable(gridViewTable, true, OfficeOpenXml.Table.TableStyles.Light1);
for (int i = 1; i <= gridViewTable.Columns.Count; i++)
{
ws.Column(i).AutoFit();
}
// **************
// HEADER
// **************
//prepare the range for the column headers
string cellRange = "B2:" + Convert.ToChar('B' + gridViewTable.Columns.Count - 1) + 2;
//Format the header for columns
using (ExcelRange rng = ws.Cells[cellRange])
{
rng.Style.WrapText = false;
rng.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
rng.Style.Font.Bold = true;
rng.Style.Fill.PatternType = ExcelFillStyle.Solid; //Set Pattern for the background to Solid
rng.Style.Fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#007A99"));
rng.Style.Font.Color.SetColor(Color.White);
}
// ************
// DATA
// ************
//prepare the range for the rows
string rowsCellRange = "B3:" + Convert.ToChar('B' + gridViewTable.Columns.Count - 1) + (gridViewTable.Rows.Count + 1);
//Format the rows
using (ExcelRange rng = ws.Cells[rowsCellRange])
{
rng.Style.WrapText = false;
rng.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
rng.Style.Fill.PatternType = ExcelFillStyle.Solid; //Set Pattern for the background to Solid
rng.Style.Fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#B2D1F0"));
rng.Style.Font.Color.SetColor(Color.Black);
}
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=" + (string.IsNullOrEmpty(FileName) ? "Report" : FileName) + ".xlsx");
Response.BinaryWrite(pck.GetAsByteArray());
}
Does anyone might know why is this happening ?

I got it.
If you use the LoadFromDataTable() method, the DataTable object should be typed in its columns, meaning that you should create the columns using
table.Columns.Add(columnName, columnType);

Related

EPPlus Array dimensions exceeded supported range. System.OutOfMemoryException

Ok so I am trying to load a CSVStream into an ExcelPackage (I am using EPPlus).
It always fails at line 221482, no matter what option I choose. I am running on x64 and I have in my app.config...
The error given is the one from the title :(
public ExcelPackage ExcelPackageFromCsvStream(Stream csvStream)
{
var excelPackage = new ExcelPackage();
var workSheet = excelPackage.Workbook.Worksheets.Add("Sheet1");
var csvFormat = new ExcelTextFormat
{
Delimiter = ',',
TextQualifier = '"',
DataTypes = new[] { eDataTypes.String }
};
using (var sr = new StreamReader(csvStream))
{
int i = 1;
foreach (var line in sr.ReadLines("\r\n"))
{
workSheet.Cells["A" + i].LoadFromText(line, csvFormat);
i++;
}
}
return excelPackage;
}
Resolved it by creating multiple ExcelPackages and also I've read the stream in batches (e.g. 200k lines at once)
public List<ExcelPackage> ExcelPackagesFromCsvStream(Stream csvStream, int batchSize)
{
var excelPackages = new List<ExcelPackage>();
int currentPackage = -1; // so that first package will have the index 0
var csvFormat = new ExcelTextFormat
{
Delimiter = ',',
TextQualifier = '"',
DataTypes = new[] {eDataTypes.String}
};
using (var sr = new StreamReader(csvStream))
{
int index = 1;
foreach (var line in sr.ReadLines("\r\n"))
{
if ((index - 1) % batchSize == 0)
{
var excelPackage = new ExcelPackage();
excelPackage.Workbook.Worksheets.Add("Sheet1");
excelPackages.Add(excelPackage);
currentPackage++;
index = 1;
}
excelPackages[currentPackage].Workbook.Worksheets.First().Cells["A" + index].LoadFromText(line, csvFormat);
index++;
}
}
return excelPackages;
}

How can I set the column properties(DisplayFormatString to be precise) of a aspx(devExpress) grid from code behind?

I have an aspx(devexpress) grid. Using which I generate columns dynamically from code behind.Below is the code from my grid_databinding event.
GridViewDataTextColumn bfield = new GridViewDataTextColumn();
if (TestString.YearSelectedNames.ToString().Length > 4)
{ string colName = string.Empty;
if (iCount % 2 == 0)
{
colName = TestString.YearSelectedNames.ToString().Substring(5, 4) + "-" + dtFreezing.Columns[iCount].ColumnName.ToString();
bfield.HeaderTemplate = new DevxGridViewTemplate(ListItemType.Header, typeof(Label), colName, iCount);
}
else
{
colName = TestString.YearSelectedNames.ToString().Substring(0, 4) + "-" + dtFreezing.Columns[iCount].ColumnName.ToString().Replace('1', ' ');
bfield.HeaderTemplate = new DevxGridViewTemplate(ListItemType.Header, typeof(Label), colName, iCount);
}
}
else
{
bfield.HeaderTemplate = new DevxGridViewTemplate(ListItemType.Header, typeof(Label), dtFreezing.Columns[iCount].ColumnName.Trim(), iCount);
}
bfield.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
bfield.HeaderStyle.Wrap = DevExpress.Utils.DefaultBoolean.True;
bfield.Name = dtFreezing.Columns[iCount].ColumnName.Trim();
bfield.Width = Unit.Pixel(120);
bfield.VisibleIndex = iCount;
bfield.DataItemTemplate = new DevxGridViewTemplate(ListItemType.Item, typeof(Label), dtFreezing.Columns[iCount].ColumnName.Trim(), iCount);
bfield.CellStyle.HorizontalAlign = HorizontalAlign.Right;
bfield.PropertiesTextEdit.DisplayFormatString = "N2";
gridViewProductCrop.Columns.Add(bfield);
Here the line of code
bfield.PropertiesTextEdit.DisplayFormatString = "N2";
is where I am trying to set the property of the grids' column to display only two decimals after the decimal point.
This line of code doesn't seem to work in the first place.
I have even tried using "{0:0.00}" and "{0:N2}" but in vain
Possible reason being that I am writing this line of code in the grid's databinding event. But how else can I set the column properties from code behind
Try to change this code
bfield.PropertiesTextEdit.DisplayFormatString = "N2";
to
this.PropertiesTextEdit.DisplayFormatString = "N2";
i think this happen coz u loop the object(make a new object) and the properties would be overwrite.
CMIIW

Dynamics AX 2009 X++ Selecting A Date Range

I am creating an X++ report, and the requirement is that the user can multi-select on a form and when they click the report menu button the values are pulled in based on the selection.
So far this is easy enough, and I can pull in Str ranges i.e. order numbers, item id's etc, but I want to be able to pull in a date range based on selection.
I have used a method which several MorphX reports use, with use of 3 key methods in X++ reporting;
setQuerySortOrder
setQueryEnableDS
and the main key one which is;
setQueryRange
The code for setQuery Range is as follows;
private void setQueryRange(Common _common)
{
FormDataSource fds;
LogisticsControlTable logisticsTable;
QueryBuildDataSource qbdsLogisticsTable;
QueryBuildRange qbrVanRun;
str rangeVanRun;
QueryBuildRange qbrLogId;
str rangeLogId;
QueryBuildRange qbrExpStartDate;
str rangeExpStartDate;
set vanRunSet = new Set(Types::String);
set logIdSet = new Set(Types::String);
set expStartDate = new Set(Types::Date);
str addRange(str _range, str _value, QueryBuildDataSource _qbds, int _fieldNum, Set _set = null)
{
str ret = _range;
QueryBuildRange qbr;
;
if(_set && _set.in(_Value))
{
return ret;
}
if(strLen(ret) + strLen(_value) + 1 > 255)
{
qbr = _qbds.addRange(_fieldNum);
qbr.value(ret);
ret = '';
}
if(ret)
{
ret += ',';
}
if(_set)
{
_set.add(_value);
}
ret += _value;
return ret;
}
switch(_common.TableId)
{
case tableNum(LogisticsControlTable):
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrVanRun = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMServiceCenterID));
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrLogId = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, LogisticsId));
// qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
// qbrExpStartDate = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMExpDateJobStart));
fds = _common.dataSource();
for(logisticsTable = fds.getFirst(true) ? fds.getFirst(true) : _common;
logisticsTable;
logisticsTable = fds.getNext())
{
rangeVanRun = addrange(rangeVanRun, logisticsTable.APMServiceCenterID, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMServiceCenterID), vanRunSet);
rangeLogID = addrange(rangeLogID, logisticsTable.LogisticsId, qbdsLogisticsTable, fieldNum(LogisticsControlTable, LogisticsId), logIdSet);
// rangeExpStartDate = addrange(rangeExpStartdate, logisticsTable.APMExpDateJobStart, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);
}
qbrLogId.value(rangeLogID);
qbrVanRun.value(rangeVanRun);
break;
}
}
Use queryValue to format your dates correctly for the query:
set expStartDate = new Set(Types::String);
rangeExpStartDate = addrange(rangeExpStartdate, queryValue(logisticsTable.APMExpDateJobStart), qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);

Dynamic parameter and query

I'm creating a search engine for my asp page.There are 15 pieces filtering options like Price,Date,Name etc.
Also,The use of Filtering Options is optional.If the filtering options are left blank,search will be made.
I found a solution by using if and string.
string sorgu = "";
dbcommand cmd = CommandClassım.YeniCommand();
sorgu += "Select * From Urunler Where ";
if(UrunAdi.Text != string.Empty)
{
sorgu += "UrunAdi = #UrunAdi";
dbparameters prm = cmd.createparameter();
prm.Parametername = "#UrunAdi";
prm.Value = UrunAdi.Text;
prm.DbType = DbType.String;
cmd.Parameters.Add(prm);
}
cmd.CommandText = sorgu;
it's running upper code without problem.However,I want to using a parameter to filter dynamic.
So,the user choose those categories through checkbox inside search engine.
When I try to run below code,I got the following error.
Must declare the scalar variable "#cat0".
Code:
string sorgu = "";
DbCommand cmd = CommandClassım.YeniCommand();
sorgu += "Select * From Urunler Where ";
DbParameter prm = cmd.CreateParameter;
for(int i = 0; i < Category.Length; i++)
{
sorgu += "Kategori = #cat" + i.ToString();
prm.ParameterName = "#cat" + i.ToString();
prm.Value = Category.Value;
prm.DbType = DbType.String;
cmd.Parameters.Add(prm);
}
cmd.CommandText = sorgu;
Just a hunch, but could it be that you're not providing the indexer for Category?
prm.Value = Category.Value;
I would think it should be:
prm.Value = Category[i].Value;

Can a gridview bound to a custom object (CSV file) be sorted?

I have a Datagrid which is getting its data from CSV. No file is sorted in any order, but I want to order the gridview by Username (a field). How could this be done? My XML/gridview code looks like the following:
Streamwriter for writing to csv and populating gridview:
string filename = #"D:\www\isolated\LocalUser\cc-suppressions\generatedsuppressions\surpressions.csv";
StreamWriter sWriter = new StreamWriter(Server.MapPath("Surpression.csv"));
string Str = string.Empty;
string headertext = "";
sWriter.WriteLine(headertext);
int cellLimit = GridView3.Rows[1].Cells.Count;
for (int i = 0; i <= (this.GridView3.Rows.Count - 1); i++)
{
for (int j = 0; j <= (this.GridView3.Rows[i].Cells.Count - 1); j++)
{
Str = this.GridView3.Rows[i].Cells[j].Text.ToString();
if (Str == " ")
Str = "";
Str = (Str + ",");
sWriter.Write(Str);
}
sWriter.WriteLine();
}
sWriter.Close();
sWriter.Dispose();
}
this.GridView3.DataBind();
You can use the ODBC driver to bind to text data. An example is
http://www.thejackol.com/2004/07/01/connect-to-a-csv-file-using-odbc-c/
You can use a data adapter to populate a DataSet object. Bind to the dataset. You should be able to sort after that.

Resources