GXT Grid export to excel file - gwt

I am using GXT.
I have a Grid.
com.sencha.gxt.widget.core.client.grid.Grid<RiaBean> grid;
I want to export this to excel file.
i dont want to use external Jar files.
Can any body Help.

Your Grid is composed of ColumnConfig<RiaBean,?>.
Every ColumnConfig<RiaBean,?> is linked to a ValueProvider<RiaBean,?>. Every ValueProvider<RiaBean,?> contains a methodgetPath() which is intended to return the path of the displayed elements.
Hence, you can easily get the paths of your displayed elements, send them to the server and get back the value by Introspection or EL.
For example, let's take this class
public class RIABean{
private String a;
private Integer b;
private Boolean c;
private Integer idFoo;
}
Use an interface which extends PropertyAccess to easily define your ValueProviders. It will also generate the methods getPath() with the accurate value.
public interface RIABeanPropertyAccess extends PropertyAccess<RIABean>{
//The generated getPath() method returns "a"
ValueProvider<RIABean,String> a();
//The generated getPath() method returns "b"
ValueProvider<RIABean,Integer> b();
//The generated getPath() method returns "c"
ValueProvider<RIABean, Boolean> c();
//The generated getPath() method returns "foo.id"
#Path("foo.id")
ValueProvider<RIABean, Integer> idFoo();
}
Create the ColumnModel for your grid:
RIABeanPropertyAccess pa=GWT.create(RIABean.class);
List<ColumnConfig<RIABean,?>> listCols=new ArrayList<ColumnConfig<RIABean,?>>();
listCols.add(new ColumnConfig(pa.a(),100,"Header text for column A");
listCols.add(new ColumnConfig(pa.b(),100,"Header text for column B");
listCols.add(new ColumnConfig(pa.c(),100,"Header text for column C");
ColumnModel colModel=new ColumnModel(listCols);
When the user clicks on "export" button, just iterate on the list of ColumnConfig<RiaBean,?> of your grid in order to get the Path of each of them and send this list of paths to the server. The server might then use introspection/reflexion/EL to get the values corresponding to each path.
There is no way to generate the file on client side. As the server must do it, it is the easiest way I know and that's what we do in my team.
Finally, ask yourself if you really need an excel file or if a csv file would be enough. The csv file can easily be done without any library and can be opened with Excel.

Related

Umbraco 7 generic node class

With the help of other Stackoverflow users, I have gone some way to my solution but have come to a halt.
I would like to build some generic classes in an app_code .cshtml file eg one would be to return property values from documents from a function eg
public static string docFieldValue(int docID,string strPropertyName){
var umbracoHelper = new Umbraco.Web.UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
var strValue = "";
try{
strValue = umbracoHelper.Content(docID).GetPropertyValue(strPropertyName).ToString();
}
catch(Exception ex){
strValue = "Error - invalid document field name (" + strPropertyName + ")";
}
var nContent = new HtmlString(strValue);
return nContent;
}
This works ok for returning one field (ie property) from a document. However, if I wanted to return 2 or more, ideally, I would store the returned node in a variable or class and then be able to fetch property values repeatedly without having to look up the document with each call
ie without calling
umbracoHelper.Content(docID).GetPropertyValue(strPropertyName).ToString();
with different strPropertyName parameters each time, as I assume that will mean multiple reads from the database).
I tried to build a class, with its properties to hold the returned node
using Umbraco.Web;
using Umbraco.Core.Models;
...
public static Umbraco.Web.UmbracoHelper umbracoHelper = new Umbraco.Web.UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
public static IPublishedContent docNode;
...
docNode = umbracoHelper.Content(docID);
but this crashed the code. Can I store the node in a property on a class, and if so, what type is it?
First of all, using a .cshtml file is unnecessary, use a .cs file instead :-) CSHTML files are for Razor code and HTML and stuff, CS files are for "pure" C#. That might also explain why your last idea crashes.
Second of all, UmbracoHelper uses Umbracos own cache, which means that the database is NOT touched with every request. I would at least define the umbracoHelper object outside of the method (so it gets reused every time the method is called instead of reinitialised).
Also, beware that property values can contain all kinds of other object types than strings.
EDIT
This is an example of the entire class file - my example namespace is Umbraco7 and my example class name is Helpers:
using Umbraco.Web;
namespace Umbraco7
{
public class Helpers
{
private static UmbracoHelper umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
private static dynamic docNode;
public static string docFieldValue(int docID, string strPropertyName)
{
docNode = umbracoHelper.Content(docID);
return docNode.GetPropertyValue(strPropertyName).ToString();
}
}
}
This is an example how the function is called inside a View (.cshtml file inside Views folder):
#Helpers.docFieldValue(1076, "introduction")
Helpers, again, is the class name I chose. It can be "anything" you want. I've just tested this and it works.
I suggest you read up on general ASP.NET MVC and Razor development, since this is not very Umbraco specific.

How to use CellTable<T> when T is an interface

in my current project I have to render items in a CellTable received via a RPC call. The columns must be created dynamically and the column types are unknown at compile time.
From the server side, I send a list of the following class to define a row in the table:
public class TableRowDTO implements IsSerializable {
private List<IsTableItemDTO> tableItemDTOs;
public TableRowDTO() {
tableItemDTOs = new ArrayList<IsTableItemDTO>();
}
// getters & setters ...
}
Where each row will contain an item implementing IsTableItemDTO which is a marker interface:
public interface IsTableItemDTO extends IsSerializable {}
Implementing classes depict the actual controls/information to be shown in cells like:
public class TableDateTimeDTO extends IsTableItemDTO {
private Date valueDate;
// ... other fields not necessary for the table
}
Or also:
public class TableCheckBoxDTO extends AbstractTableItemDTO {
private boolean checked;
// ... other fields not necessary for the table
}
And also:
TablePasswordDTO extends AbstractTableItemDTO {
private String valueText;
// ... other fields not necessary for the table
}
Therefore, what I want to do for example in the case I receive a List with {TableCheckBoxDTO, TableDateTimeDTO, TablePasswordDTO} is to render a CellTable with the corresponding widgets.
I've seen this and this, but I don't see how to apply any of the examples to my case especially because I cannot use thigs like Column as I don't have my ContactInfo before hand.
Thanks
You can use the marker interface IsTableItemDTO together with instanceof() and dynamic casts to have a generic Column/Cell.
There are 2 ways:
Create a Composite Cell and add all possible cell types and then display based on what specific sub-type your isTableItemDTO is.
Create a custom cell and render the input (checkbox, text) based on the specific type of your marker interface
I used Jet table (https://code.google.com/p/gwt-jet/) in one of my earlier projects. I believe it has the features you are looking for.

How to store a unique value into a Panel (GWT)?

This is simple question but there's No answer found on the Internet.
Ok, some widgets such as CheckBox have a method called myCHeckBox.setFormValue(text); so I take advantage of this method to store the unique ID into a CheckBox so that later on I just myCHeckBox.getFormValue(); to retrieve back the unique value.
However, there's no setFormValue on GWT Panel?
So if we want to store a unique value into a Panel (for example, FlowPanel, VerticalPanel)?
Then Which method can i use to do that?
The way I see it what you are really trying is to extend the purpose of the Panel. I cannot see why you would want a unique identifier, as the object of the Panel is as unique as it guess but that's not the point here.
Since you want to extend the Panel do just that. Extend the corresponding class and give it a unique value, implement the corresponding getters and setters and then you are set. It is as simple as that
class AbsolutePanelUnq extends AbsolutePanel
{
private int uniqueId;
public getUniqueId(){
return uniqueId;
}
public setUniqueId(int uniqueId)
{
this.uniqueId = uniqueId;
}
}
Then create the object and do whatever you need.
Best way I can suggest:
Public class myPanel extends Panel {
private myUniqueValue;
//Getter setter for myUniqueValue
}

How to use the sqoop generated class in MapReduce?

A sqoop query generates a java file that contains a class that contains the code to get access in mapreduce to the columns data for each row. (the Sqoop import was done in text without the --as-sequencefile option, and with 1 line per record and commas between the columns)
But how do we actually use it?
I found a public method parse() in this class that takes Text as an input and populates all the members of the class , so to practice I modified the wordcount application to convert a line of text from the TextInputFormat in the mapper into an instnace of the class generated by sqoop. But that causes an "unreported exception.com.cloudera.sqoop.lib.RecordParser.ParseError; must be caught or declared to be thrown" when I call the parse() method.
Can it be done this way or is a custom InputFormat necessary to populate the class with the data from each record ?
Ok this seems obvious once you find out but as a java beginner this can take time.
First configure your project:
just add the sqoop generated .java file in your source folder.
I use eclipse to import it in my class source folder.
Then just make sure you configured your project's java build path correctly:
Add the following jar files in the project's properties/java build path/libraries/add external jar:
(for hadoop cdh4+) :
/usr/lib/hadoop/hadoop-common.jar
/usr/lib/hadoop-[version]-mapreduce/hadoop-core.jar
/usr/lib/sqoop/sqoop-[sqoop-version]-cdh[cdh-version].jar
Then adapt your mapreduce source code:
First configure it:
public int run(String [] args) throws exception
{
Job job = new Job(getConf());
job.setJarByClass(YourClass.class);
job.setMapperClass(SqoopImportMap.class);
job.setReducerClass(SqoopImprtReduce.class);
FileInputFormat.addInputPath((job,"hdfs_path_to_your_sqoop_imported_file"));
FileOutputFormat.setOutputPath((job,"hdfs_output_path"));
// I simply use text as output for the mapper but it can be any class you designed
// as long as you implement it as a Writable
job.setMapOutputKeyClass(Text.Class);
job.setMapOutputValueClass(Text.Class);
job.setOutputKeyClass(Text.Class);
job.setOutputValueClass(Text.Class);
...
Now configure your mapper class.
Let's assume your sqoop imported java file is called Sqimp.java:
and the table you imported had the following columns: id, name, age
your mapper class should look like this:
public static class SqoopImportMap
extends Mapper<LongWritable, Text, Text, Text>
{
public void map(LongWritable k, Text v, Context context)
{
Sqimp s = new Sqimp();
try
{
// this is where the code generated by sqoop is used.
// it automatically casts one line of the imported data into an instance of the generated class,
// to let you access the data inside the columns easily
s.parse(v);
}
catch(ParseError pe) {// do something if there is an error.}
try
{
// now the imported data is accessible:
// e.g
if (s.age>30)
{
// submit the selected data to the mapper's output as a key value pair.
context.write(new Text(s.age),new Text(s.id));
}
}
catch(Exception ex)
{//do something about the error}
}
}

NUnit TestCaseSource pass value to factory

I'm using the NUnit 2.5.3 TestCaseSource attribute and creating a factory to generate my tests. Something like this:
[Test, TestCaseSource(typeof(TestCaseFactories), "VariableString")]
public void Does_Pass_Standard_Description_Tests(string text)
{
Item obj = new Item();
obj.Description = text;
}
My source is this:
public static IEnumerable<TestCaseData> VariableString
{
get
{
yield return new TestCaseData(string.Empty).Throws(typeof(PreconditionException))
.SetName("Does_Reject_Empty_Text");
yield return new TestCaseData(null).Throws(typeof(PreconditionException))
.SetName("Does_Reject_Null_Text");
yield return new TestCaseData(" ").Throws(typeof(PreconditionException))
.SetName("Does_Reject_Whitespace_Text");
}
}
What I need to be able to do is to add a maximum length check to the Variable String, but this maximum length is defined in the contracts in the class under test. In our case its a simple public struct:
public struct ItemLengths
{
public const int Description = 255;
}
I can't find any way of passing a value to the test case generator. I've tried static shared values and these are not picked up. I don't want to save stuff to a file, as then I'd need to regenerate this file every time the code changed.
I want to add the following line to my testcase:
yield return new TestCaseData(new string('A', MAX_LENGTH_HERE + 1))
.Throws(typeof(PreconditionException));
Something fairly simple in concept, but something I'm finding impossible to do. Any suggestions?
Change the parameter of your test as class instead of a string. Like so:
public class StringTest {
public string testString;
public int maxLength;
}
Then construct this class to pass as an argument to TestCaseData constructor. That way you can pass the string and any other arguments you like.
Another option is to make the test have 2 arguments of string and int.
Then for the TestCaseData( "mystring", 255). Did you realize they can have multiple arguments?
Wayne
I faced a similar problem like yours and ended up writing a small NUnit addin and a custom attribute that extends the NUnit TestCaseSourceAttribute. In my particular case I wasn't interested in passing parameters to the factory method but you could easily use the same technique to achieve what you want.
It wasn't all that hard and only required me to write something like three small classes. You can read more about my solution at: blackbox testing with nunit using a custom testcasesource.
PS. In order to use this technique you have to use NUnit 2.5 (at least) Good luck.