Example: Let say A,B,C are columns and 1,2,3 are rows in a sheet.For A column 1,2,3 rows need to merge display as single rows how using spreadsheet gear
A B C
1
2
3
I'm not sure what you mean about dynamically generating headers. What is your source of data? To merge columns or rows, you can use the Merge method of the IRange class.
workbookView1.ActiveWorksheet.Cells["A1:A3"].Merge()
Merging into one cell will keep the upper-left most data only.
What you can do is use reflection to send a Enumerable type and convert it to DataTable.
private static DataTable ConvertToDataTable(IEnumerable<T> enumerable)
{
var properties = TypeDescriptor.GetProperties(typeof(T));
var table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (var item in enumerable)
{
var row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}
After that let the spreadsheet gear do its job.
Convert it to memory stream and then to byte[]
Pass the byte[] to FileContentResult
Related
Right now i am able to read data from the column in the single returned row ad below
var resultsDoc = await conn
.query('select fNAME, SPECIALITY, CATENAME from doctor where id = ?', [5]);
for (var rowDoc in resultsDoc) {
ffname = rowDoc[0]; //reading value at column 1
sspeciality = rowDoc[1]; //reading value at column 2
ccategory = rowDoc[2]; //reading value at column 3
}
what if i wanted to return the entire table as below
enter image description here
Team, assist on how to read those values.
Thank You
You were close!
for (var rowDoc in resultsDoc) {
print(rowDoc.join('\t'));
}
Or did you want to transpose the list of lists, so that you'd have 3 lists, one for each column?
I have a datatable with two columns ID & Role.
Same ID can have multiple roles.
I need to convert this table to a comma separated grouped table.
I am trying to use following query but unable to solve the issue.
LINQ:
From row As DataRow In dtData.Rows.Cast(Of DataRow)
Group row By id = row.Field(Of Integer)("ID") Into Group
Select ID, Role = String.Join(",", From i In Group Select i.Field(Of String)("Role"))
Issue
Any help will be appreciated.
Update 1:
Table structure
Needed table Structure
You could create a linq like in your comments just that this returns a list of arrays of string:
Here is the code:
(From row As DataRow In myDatatable
Group row By id = row.Field(Of String)("ID") Into Group
Select {id, String.Join(",", From i In Group Select i.Field(Of String)("Role"))}).ToList
If you need the result in a datatable you can build a new datatable
Make a for each of result and use the activity Add data row. In ArrayRow add the item and in DataTable the new data table
If you use the activity Output data table you can see the results
I am kind of confused by what you are wanting as the ultimate outcome. An idea that may guide you but not be exactly what you want is you can change a DataTable to an anonymous projection and then get what you want out of that. You can do a 'Select' off a DataTable which enters into an extension method of 'what' do you want to select. If I was to do a new {} without any class or container object after the 'new' I would be scoped to just a method or not. This is a good advantage when you want to mold something for a specific use in just a single method to use tailored to a specific view.
static void Main(string[] args)
{
DataTable d = new DataTable();
d.Columns.Add("ItemName", typeof(string));
d.Columns.Add("MinValue", typeof(float));
d.Columns.Add("MaxValue", typeof(float));
d.Rows.Add("Widget1", 0.1, 0.2);
d.Rows.Add("Widget2", 0.2, 0.4);
d.Rows.Add("Widget3", 0.1, 0.2);
var dataTable = d.AsEnumerable();
//What do you want to select? The new {} without an indicator means anonymous type projection. This will exist only in
// the scope listed.
var data = dataTable.Select(x => new { ItemName = x[0], MinValue = x[1], MaxValue = x[2] }).ToList();
//My 'data' type is now well typed for it's properties in the scope it's in.
var joined = String.Join(", ", data.Select(x => x.ItemName).ToList());
Console.WriteLine(joined);
Console.WriteLine($"{data.Count}");
Console.ReadLine();
}
EDIT 1-26-18
Strange I thought I updated the code yesterday. To get a reusable object you could bind your front end to, you just make a POCO like so:
public class Foo
{
public string Bar { get; set; }
public string MinAndMax { get; set; }
}
While you could make another DataTable, frankly DataTables are like WinForms. They get the job done, but they are archaic and not friendly to do Linq with as easily as just a well formed POCO. And if you get into using Linq it will play better with well formed objects and they are easy to create.
var data = dataTable.Select(x => new Foo { Bar = x[0].ToString(), MinAndMax = $"{x[1]} {x[2]}" }).ToList();
//My 'data' type is now well typed for 'Foo' class and it's properties in the scope it's in.
var joined = String.Join(", ", data.Select(x => $"{x.Bar} {x.MinAndMax}").ToList());
I have a resultSet which is having multiple rows. I want to make a hashmap. But while storing the arrayList and making key as one of the columns, for each key all the rows are stored in arrayList.
That means for each key all the rows are stored rather than the exact rows for that key.
HashMap> map = new HashMap>();
Pojo pojo = null;
PreparedStatement ps = null;
ResultSet rs = null;
ArrayList list = null;
try {
ps = DatabaseManager.prepareStatement(query);
ps.setInt(1, number);
rs = ps.executeQuery();
while(rs.next()){
pojo = new Pojo();
pojo.setId(rs.getInt("ID"));
pojo.setDate(rs.getDate("DATE"));
pojo.setTotal(rs.getDouble("TOTAL"));
list.add(pojo); map.put(rs.getInt("ID"), list);
}
rs.close();
So for all the keys the size of list is 15. While it should be like
ID Rows
1A 3
2A 4
3C 2
4W 6
So how the code should be to get the desired result?
You can try something like this,
while(rs.next()){
// Check if map contains list
if (map.contains(rs.getInt("ID"))
list = map.get(rs.getInt("ID"));
else
list = new ArrayList<Pojo>();
pojo = new Pojo();
pojo.setId(rs.getInt("ID"));
pojo.setDate(rs.getDate("DATE"));
pojo.setTotal(rs.getDouble("TOTAL"));
list.add(pojo);
map.put(rs.getInt("ID"), list);
}
Hope it works.
Somehow i got filename.log which looks like for example (tab separated)
Name:Peter Age:18
Name:Tom Age:25
Name:Jason Age:35
because the value of key column may differ i cannot define schema when i load text like
a = load 'filename.log' as (Name:chararray,Age:int);
Neither do i want to call column by position like
b = foreach a generate $0,$1;
What I want to do is, from only that filename.log, to make it possible to call each value by key, for example
a = load 'filename.log' using PigStorage('\t');
b = group b by Name;
c = foreach b generate group, COUNT(b);
dump c;
for that purpose, i wrote some Java UDF which seperate key:value and get value for every field in tuple as below
public class SPLITALLGETCOL2 extends EvalFunc<Tuple>{
#Override
public Tuple exec(Tuple input){
TupleFactory mTupleFactory = TupleFactory.getInstance();
ArrayList<String> mProtoTuple = new ArrayList<String>();
Tuple output;
String target=input.toString().substring(1, input.toString().length()-1);
String[] tokenized=target.split(",");
try{
for(int i=0;i<tokenized.length;i++){
mProtoTuple.add(tokenized[i].split(":")[1]);
}
output = mTupleFactory.newTupleNoCopy(mProtoTuple);
return output;
}catch(Exception e){
output = mTupleFactory.newTupleNoCopy(mProtoTuple);
return output;
}
}
}
How should I alter this method to get what I want? or How should I write other UDF to get there?
Whatever you do, don't use a tuple to store the output. Tuples are intended to store a fixed number of fields, where you know what every field contains. Since you don't know that the keys will be in Name,Age form (or even exist, or that there won't be more) you should use a bag. Bags are unordered sets of tuples. They can have any number of tuples in them as long as the tuples have the same schema. These are all valid bags for the schema B: {T:(key:chararray, value:chararray)}:
{(Name,Foo),(Age,Bar)}
{(Age,25),(Name,Jim)}
{(Name,Bob)}
{(Age,30),(Name,Roger),(Hair Color,Brown)}
{(Hair Color,),(Name,Victor)} -- Note the Null value for Hair Color
However, it sounds like you really want a map:
myudf.py
#outputSchema('M:map[]')
def mapize(the_input):
out = {}
for kv in the_input.split(' '):
k, v = kv.split(':')
out[k] = v
return out
myscript.pig
register '../myudf.py' using jython as myudf ;
A = LOAD 'filename.log' AS (total:chararray) ;
B = FOREACH A GENERATE myudf.mapize(total) ;
-- Sample usage, grouping by the name key.
C = GROUP B BY M#'Name' ;
Using the # operator you can pull out all values from the map using the key you give. You can read more about maps here.
I have a webservice I call from a WP7 app. I get a list of high scores in a table (name/score).. What is the simpliest way to add a 3rd column on the far left which is simply the row?
Do I need to add a property to the entity? Is there someway to get the row #?
I tried these things below with no success..
[OperationContract]
public List<DMHighScore> GetScores()
{
using (var db = new DMModelContainer())
{
// return db.DMHighScores.ToList();
var collOrderedHighScoreItem = (from o in db.DMHighScores
orderby o.UserScore ascending
select new
{
o.UserName,
o.UserScore
}).Take(20);
var collOrderedHighScoreItem2 = collOrderedHighScoreItem.AsEnumerable().Select((x, i) => new DMHighScoreDTO
{
UserName = x.UserName,
UserScore = x.UserScore
}).ToList();
}
}
[DataContract]
public class DMHighScoreDTO
{
int Rank;
string UserName;
string UserScore;
}
So lets assume you want to load top 100 users in leaderboard and you want to have their rank included:
[OperationContract]
public List<ScoreDto> GetTop100()
{
// Linq to entities query
var query = (from u from context.Users
order by u.Score
select new
{
u.Name,
u.Score
}).Take(100);
// Linq to objects query from working on 100 records loaded from DB
// Select with index doesn't work in linq to entities
var data = query.AsEnumerable().Select((x, i) => new ScoreDto
{
Rank = i + 1,
Name = x.Name,
Score = x.Score
}).ToList();
return data;
}
what will the row number be used for? if this is for ordering might I suggest adding a column named Order, then map the column to your entity.
if you require a row index, you could also call the .ToList() on the query and fetch the index locations for each entity.
Edit:
you could add the Rank property and set it to Ignore. This will enable you to go through the collection set the rank with a simple for loop. This will also not be persisted in the database. It will also not have any required columns in the database.
It does add an extra iteration.
the other way to go about it. This would be to add the rank number in the generated UI and not in the data collection being used to bind.