How to configure ExcelReaderFactory to solve problem of Encoding in c#? - c#

I use ExcelDataReader.DataSet nuggetPackage
var reader = ExcelReaderFactory.CreateReader(stream);
var conf = new ExcelDataSetConfiguration
{
UseColumnDataType = true,
FilterSheet = (tableReader, sheetIndex) => true,
ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
{
EmptyColumnNamePrefix = "Column",
UseHeaderRow = false,
}
}
};
var dataSet = reader.AsDataSet(conf);
I have the data in the dataset but some characters became ? (é => ?, ç => ?)
i try to use ExcelReaderConfiguration but i didn't find how to use dataset with this.
var readerConf = ExcelReaderFactory.CreateReader(stream, new ExcelReaderConfiguration()
{
FallbackEncoding = Encoding.GetEncoding(1252),
AutodetectSeparators = new char[] { ',', ';', '\t', '|', '#' },
LeaveOpen = false,
AnalyzeInitialCsvRows = 0,
});

Related

ExcelDataReader : I have 5 columns, the code creates one more "Column6": null . Any idea on how to avoid this or filter it?

I am using the following code-
private static HashSet<string> keepHeaders = new HashSet<string>{
"Screen", "Section", "Question Name", "Question Label",
"Question Type", "Required?", "Choice Group",
"Min", "Max", "Max Length", "Label", "Choice Label",
"Name", "Description"
};
private static string ExtractDataCatalogAlt(IFormFile file)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var excelStream = file.OpenReadStream())
using (var reader = ExcelReaderFactory.CreateOpenXmlReader(excelStream, new ExcelReaderConfiguration { FallbackEncoding = Encoding.GetEncoding(1252) }))
{
var headers = new List<string>();
var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration
{
UseHeaderRow = true,
ReadHeaderRow = (r) =>
{
// store the header row values so we can trim columns out that don't have headers
for (var i = 0; i < r.FieldCount; i++)
headers.Add(r.GetString(i));
},
FilterColumn = (_, c) =>
{
return keepHeaders.Contains(headers[c]);
}
}
});
return JsonConvert.SerializeObject(dataSet, Formatting.Indented);
}
}
Can you tell what condition should I put in FilterColumn so that it reads only cells which has values and not give output as "column6" : null

LINQ: dynamic Where clause with toggle the combination of cases

I have a list binded to angridview and i want to be able to create filter Where clause 'on the fly',
while the combination of filter option controlled by user.
What is the best way to filter the original list by model boolean property and allow to toggle every condition of filter?
I know that the filterdList is not nececery, but every other solution i've already saw doesn't allow toggle the condition of Where clause.
public partial class Form1 : Form
{
List<dummy> Origlist = new List<dummy> {
new dummy { pk = 1 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 2 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 3 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 4 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 5 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 6 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 7 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 8 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 9 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 10 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 11 , istype1 = false, istype2 = false, istype3=false, istype4=false }
};
List<dummy> filteredList = new List<dummy>();
public Form1()
{
InitializeComponent();
}
private void Bind()
{
dataGridView1.DataSource = null;
dataGridView1.DataSource = filteredList;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
filteredList.AddRange(Origlist.Where(a => a.istype1 == true).ToList());
}
else
{
filteredList.RemoveAll(a => a.istype1 == true);
}
Bind();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
filteredList.AddRange(Origlist.Where(a => a.istype2 == true).ToList());
}
else
{
filteredList.RemoveAll(a => a.istype2 == true);
}
Bind();
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
filteredList.AddRange(Origlist.Where(a => a.istype3 == true).ToList());
}
else
{
filteredList.RemoveAll(a => a.istype3 == true);
}
Bind();
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
if (checkBox4.Checked)
{
filteredList.AddRange(Origlist.Where(a => a.istype4 == true).ToList());
}
else
{
filteredList.RemoveAll(a => a.istype4 == true);
}
Bind();
}
}
Try something like this (untested):
public partial class Form1 : Form
{
List<dummy> Origlist = new List<dummy> {
new dummy { pk = 1 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 2 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 3 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 4 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 5 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 6 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 7 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 8 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 9 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 10 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 11 , istype1 = false, istype2 = false, istype3=false, istype4=false }
};
Options options = new Options();
private class Options {
public bool istype1 { get; set; }
public bool istype2 { get; set; }
public bool istype3 { get; set; }
public bool istype4 { get; set; }
}
public Form1()
{
InitializeComponent();
}
private void Bind()
{
dataGridView1.DataSource = null;
dataGridView1.DataSource = OrigList.Where(a =>
(options.istype1 && a.istype1) ||
(options.istype2 && a.istype2) ||
(options.istype3 && a.istype3) ||
(options.istype4 && a.istype4)
).ToList();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
options.istype1 = checkBox1.checked;
Bind();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
options.istype2 = checkBox2.checked;
Bind();
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
options.istype3 = checkBox3.checked;
Bind();
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
options.istype4 = checkBox4.checked;
Bind();
}
}
There are other ways you could reduce duplication, but this is a start.
I would say that the easiest/cleanest way is using ADO.NET DataSet for handling your data instead of a using a bunch of List with some Linq query. ADO.NET DataSet is the Official Winforms Way of life.
You could use these dataset/datatable with a BindingSource component as the DataSource of your DataGridView and use the Filter String Property of the BindingSource. This String expression could be easily build by some If clauses testing the state of your CheckBox and String concatenation following the MSND DataColumn Expression syntax.
There are some other clean way like extending the BindingList class with a partial implementation of the IBindingListView interface. But that's some pretty hard stuff, specially when you know that Microsoft has done this work for you for the DataSet... This article is a good place to start if you are not afraid.
a single event handler can be reused for every CheckBox, and that event handler can compare every property with respective CheckBox.
List<dummy> Origlist = new List<dummy>
{
new dummy { pk = 1 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 2 , istype1 = true, istype2 = false, istype3=false, istype4=false },
new dummy { pk = 3 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 4 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 5 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 6 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 7 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 8 , istype1 = false, istype2 = false, istype3=false, istype4=true },
new dummy { pk = 9 , istype1 = false, istype2 = false, istype3=true, istype4=false },
new dummy { pk = 10 , istype1 = false, istype2 = true, istype3=false, istype4=false },
new dummy { pk = 11 , istype1 = false, istype2 = false, istype3=false, istype4=false }
};
public Form1()
{
InitializeComponent();
}
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
dataGridView1.DataSource = Origlist.Where(a =>
a.istype1 == checkBox1.Checked &&
a.istype2 == checkBox2.Checked &&
a.istype3 == checkBox3.Checked &&
a.istype4 == checkBox4.Checked).ToList();
}

NetSuite Web API - How to return/populate customFieldList array for Sales Order from a joined search?

I am currently performing a SuiteTalk search via C# that joins multiple tables, one of which is for Sales Orders. When performing a typical GET on a SalesOrder record, the property customFieldList gets populated with an array of transaction custom fields/etc. I am curious how to get the same when doing a search like:
SearchResult searchResult = Client.Service.search(new TransactionSearchAdvanced()
{
criteria = new TransactionSearch()
{
basic = new TransactionSearchBasic()
{
type = new SearchEnumMultiSelectField()
{
#operator = SearchEnumMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new String[] { "_salesOrder" },
},
lastModifiedDate = new SearchDateField()
{
#operator = SearchDateFieldOperator.after,
operatorSpecified = true,
searchValue = fromLastModifiedDateTime.ToUniversalTime(),
searchValueSpecified = true
}
},
},
columns = new TransactionSearchRow()
{
basic = new TransactionSearchRowBasic()
{
internalId = new SearchColumnSelectField[] { new SearchColumnSelectField() },
tranId = new SearchColumnStringField[] { new SearchColumnStringField() },
tranDate = new SearchColumnDateField[] { new SearchColumnDateField() },
dateCreated = new SearchColumnDateField[] { new SearchColumnDateField() },
item = new SearchColumnSelectField[] { new SearchColumnSelectField() },
quantity = new SearchColumnDoubleField[] { new SearchColumnDoubleField() },
lastModifiedDate = new SearchColumnDateField[] { new SearchColumnDateField() },
email = new SearchColumnStringField[] { new SearchColumnStringField() },
//customFieldList = new SearchColumnCustomField[] { },
},
itemJoin = new ItemSearchRowBasic()
{
itemId = new SearchColumnStringField[] { new SearchColumnStringField() },
type = new SearchColumnEnumSelectField[] { new SearchColumnEnumSelectField() },
},
customerJoin = new CustomerSearchRowBasic()
{
internalId = new SearchColumnSelectField[] { new SearchColumnSelectField() },
billAddress = new SearchColumnStringField[] { new SearchColumnStringField() },
companyName = new SearchColumnStringField[] { new SearchColumnStringField() },
phone = new SearchColumnStringField[] { new SearchColumnStringField() },
email = new SearchColumnStringField[] { new SearchColumnStringField() },
},
customSearchJoin = new CustomSearchRowBasic[]
{
},
}
});
The property I want populated is commented out within the TransactionSearchRowBasic object:
//customFieldList = new SearchColumnCustomField[] { },
Any ideas? Thank you in advance!
The search operation doesn't return as much information as a GET operation does on the SuiteTalk Web Services.
For each record that is returned in your SearchResult, use the internalId or document number to GET that record. This should then include your custom fields.
NetSuiteService _service = new NetSuiteService();
ReadResponse res = _service.get(new RecordRef { internalId = internalID, type = RecordType.salesOrder, typeSpecified = true });

Initialize array with a mix of with hard-coded and generated values

This code which initializes an array with two hard-coded values is working perfectly fine:
var db = new GoogleGraph {
cols = new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" }
}.ToList(),
rows = new List<DataPointSet>()
};
db.cols.AddRange(listOfValues.Select(p => new ColInfo { id = "", label = p, type = "number" }));
This code which attempts to add some dynamically generated values is not working:
var db = new GoogleGraph {
cols = new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" },
listOfValues.Select(p => new ColInfo { id = "", label = p, type = "number" })
}.ToList(),
rows = new List<DataPointSet>()
};
How can I correctly implement the above snippet?
You can't pass an IEnumerable<T> to an initializer of T[] like that.
You can do what you want by putting the hard-coded objects in their own collection, then concatenating the dynamic ones:
var db = new GoogleGraph {
cols =
new ColInfo[] {
new ColInfo { id = "", label = "Date", pattern ="", type = "string" },
new ColInfo { id = "", label = "Attendees", pattern ="", type = "number" }
}
.Concat(listOfValues.Select(p =>
new ColInfo { id = "", label = p, type = "number" }))
.ToList(),
rows = new List<DataPointSet>()
};

Ext.net gridview columns getting distorted in IE 8

i'm generating EXT.NET gridview dynamically as below,
public GridPanel GetGridView()
{
return new GridPanel
{
Border = false,
ID = "grd",
Cls = "x-grid-custom",
StyleSpec = "margin-top:7px; margin-left:-2px",
Scroll = ScrollMode.Both,
OverflowX = Overflow.Auto,
EnableColumnHide = false,
ColumnLines = true,
ForceFit = false,
//Width = 1100,
EmptyText = "No rows to display",
Store = { this.CreateTabularStore() },
ColumnModel =
{
Columns = {
new DateColumn {ID="ED", Text = "Effective Date",Wrap = true,DataIndex = "ED",Format="dd MMM yyyy",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 110},
new Column {ID="PRICE", Text = "Price",DataIndex = "PRICE",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 70},
new Column {ID="CURRENCY", Text = "Currency",DataIndex = "CURRENCY",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 80},
new Column {ID="OFFICIAL",Text = "Official Price",DataIndex = "OFFICIAL",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 100},
new DateColumn {ID="MARKETED_EFFECTIVE_DATE", Text = "Marketed Effective Date",DataIndex = "MARKETED_EFFECTIVE_DATE",Format="dd MMM yyyy",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 100},
new Column {ID="MARKETING_DESC", Text = "Marketed",DataIndex = "MARKETING_DESC",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 80},
new DateColumn {ID="DISCONTINUED_TS", Text = "Date Discontinued",DataIndex = "DISCONTINUED_TS",Format="dd MMM yyyy",Groupable = true, Html="<i class='prfl_unfilter_icon' onclick='return ShowGridFilter(this);'></i>" ,Width = 100},
}
},
Features = {
new Grouping(){HideGroupedHeader=false }
},
View = { new Ext.Net.GridView() { LoadMask = true, LoadingText = "Loading..." } }
};
}
below is how i defined store in a method named CreateTabularStore():
Store store;
Model model;
store = new Store();
store.ID = "StorePD";
model = new Model();
model.Fields.AddRange(new ModelField[] {
new ModelField("ED",ModelFieldType.Date),
new ModelField("PRICE", ModelFieldType.Float),
new ModelField("CURRENCY"),
new ModelField("OFFICIAL"),
new ModelField("MARKETED_EFFECTIVE_DATE",ModelFieldType.Date),
new ModelField("MARKETING_STATUS_DESC"),
new ModelField("DISCONTINUED_TS",ModelFieldType.Date)
}
);
when i filter grid with DateColumn filter, grid columns are rendering distorted in IE 8 Browser as shown in the image below

Categories