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
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;
}
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
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);
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;
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.