Does poi-objectmapper maps the excel sheet to a nested object? If so, what should be done? - excel

I'm trying to map the excel sheet to pojo using poi-object-mapper. It is working fine if the excel header name matches with the property name. But not working on a nested object.
I have a Employee Object that has a address object. How to map the street name in excel sheet to address.streetname?
public class Employee {
//#SheetColumn("Name")
private String name;
//#SheetColumn("Age")
private Integer age;
private Address address;
}

Related

Worksheets vs. Worksheets(1), can't I do this from .net interop?

Our object model contains a class called Unit and a collection of these called Units (which is stored in a Dictionary). These objects have unique Names and Keys (they originally came from a SQL db that enforced this) so I have added:
Public Units(N as String) As Unit ...
Public Units(K as Integer) As Unit...
which return a Unit object from the Units collection.
In Excel VBA, one can refer to most objects using similar methods; Worksheets(1) returns the first sheet, while Worksheets("Bob") returns the named sheet. But they have one additional method, Worksheets, which returns the entire collection. It's as if they have this method...
Public Worksheets() As List(Of Worksheet)
But you can't use List in interop (right?) so it's more like...
Public Worksheets() As ArrayList
So how would I do the same basic API in .net with interop? That is, have three methods...
Public Units(N as String) As Unit ...
Public Units(K as Integer) As Unit...
Public Units() As ArrayList...
As I understand it only the first method of a given name is exported (is this correct?). So how does Excel do it, and can I fake that in .net?
VBA's Worksheets is not a method. It is a class, Worksheets, that has a default property Item that accepts a parameter of type Variant. There is no overloading (COM does not support it), it's just that Variant can hold both a number or a string.
If you want a similar structure in VB.NET, you can have a collection class that implements a default property as VB.NET understands it, and this time you can overload it.
Public Class UnitsCollection
Default Public ReadOnly Property Item(ByVal i As Integer) As Unit
Get
Return ...
End Get
End Property
Default Public ReadOnly Property Item(ByVal i As String) As Unit
Get
Return ...
End Get
End Property
End Class

jxls collection printing order

This is my excel template. Unfortunately, employee.email is ArrayList and can have more than one value.
The result becomes
Actually, aaa1.gmail.com and aaa2.gmail.com belong to AAA and similarly, bbb1.gmail.com and bbb2.gmail.com belong to BBB. The excel output is very misleading in this case.
Is it possible to get as below?
Since I am very new to jxls, any help is really appreciate.
First you need to have a POJO like below to hold the data.
public class Employee {
private int id = 0;
private String name = null;
private List<String> mails = new ArrayList<String>();
// getters & setters
}
Now create data objects that you want to display in your excel file
Employee emp1 = new Employee();
emp1.setId(1);
emp1.setName("AAA");
emp1.getMails().add("aaa1#xyz.com");
emp1.getMails().add("aaa2#xyz.com");
Employee emp2 = new Employee();
emp2.setId(2);
emp2.setName("BBB");
emp2.getMails().add("bbb1#xyz.com");
emp2.getMails().add("bbb2#xyz.com");
List<Employee> employees = new ArrayList<Employee>();
employees.add(emp1);
employees.add(emp2);
then add the data into java.util.Map
Map<String, List<Employee>> beanParams = new HashMap<String, List<Employee>>();
beanParams.put("employees", employees);
then create XLSTransformer object and set the source file, destination file and the map which is holding your data
XLSTransformer former = new XLSTransformer();
former.transformXLS(srcFilePath, beanParams, destFilePath);
you need to use two <jx:forEach> tags to iterate over the list which is in your map and then you can set the values into your result excel file.
Change your excel template file with the following
and the final result will look like

Map a flat structure to an object with AutoMapper?

The data being returned from a stored procedure has 3 columns of repeating data:
Name | Address | PhoneNumber | UniqueCol1 | UniqueCol2
Ideally I want my model to show that there is repeated data by only storing the values once and have a collection of the unique data.
public class MyViewModel
{
public string Name {get;set;}
public string Address {get;set;}
public string PhoneNumber {get;set;}
public List<MyModel> UniqueData {get;set;}
public class MyModel
{
public string UniqueCol1 {get;set;}
public string UniqueCol2 {get;set;}
}
}
This means I want to map a collection of results to a single object of MyViewModel:
return Mapper.Map<List<StoredProcedureObject>, MyViewModel>(result);
This is where I get my error as I assume I have some configuration that I need to do:
Mapping types:
List`1 -> MyViewModel
Any ideas on the missing step to get this to work?
Automapper is only able to flatten your structure into something simpler. But it's not possible to map a simple class to something more specific.
I would suggest to take only the first entry in your table to fill your base fields like Name, Address, PhoneNumber and iterate over your results to fill your UniqueData List.
I don't see an easier way, because with each possible mapping and without using seperate loops you will get your base data multiple times.
If you don't mind to use another tool, maybe you will have a look at ValueInjecter. I heard you can use this tool for two-way-mappings.

excel 2003 vba.. writing arraylist

I am trying to create ArrayList of Class like in Java, in Visual Basic Excel 2003.
Java
List<Employee> employees = new ArrayList<Employee>();
Employee employee = new Employee();
employee.setName("tom");
employees.add(employee);
VB
Dim resultList As New Collection
Dim Manager As Employee
Manager.Name = "df"
resultList.Add ("rr") 'correct
resultList.Add (Manager) 'error
But this gives the following error:
only user-define types defined in public object modules can be coerced
to or from a variant or passed to late-bound functions
There is no type information associated with a UDT so it can't be added to a collection as there is no way to reliably convert to/from a variant as the number & types of its members is unknown.
You can either replace the Employee Type with a Class or as you don't appear to be using a key, a typed array: arr() as Employee

Parent and Child object in SimpleRepository

How would it work in Subsonic's SimpleReporitory if I wanted to be able to have a 1 to many relationship between objects?
Would I have to create a bridge object and then build my parent object at runtime, or is this support built in?
What I am looking for is the folowing:
Adam's Example Shop...
Public Class Shop
Private m_id As Integer
Private m_Name As String
Private m_Employees As List(Of Employee)
Public Property Id() As Integer
Get
Return m_id
End Get
Set(ByVal value As Integer)
m_id = value
End Set
End Property
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = value
End Set
End Property
Public Property Employees() As List(Of Employee)
Get
Return m_Employees
End Get
Set(ByVal value As List(Of Employee))
m_Employees = value
End Set
End Property
End Class
Public Class Employee
Private m_id As Integer
Private m_Name As String
Public Property Id() As Integer
Get
Return m_id
End Get
Set(ByVal value As Integer)
m_id = value
End Set
End Property
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = value
End Set
End Property
End Class
Main bits:
Dim repo As New SimpleRepository("SubSonicObjectTest", SimpleRepositoryOptions.RunMigrations)
Dim emplyee1 As New Employee
emplyee1.Name = "Martin"
Dim emplyee2 As New Employee
emplyee2.Name = "Adam"
Dim shop As New Shop
shop.Name = "Sub Sonic Store"
shop.Employees = New List(Of Employee)
shop.Employees.Add(emplyee1)
shop.Employees.Add(emplyee2)
repo.Add(Of Shop)(shop)
I think this should create 3 tables:
Shops
Employees
ShopsToEmployees (or some other naming convention)
But I only get a Channels table!
I'm updating the SimpleRepo stuff currently to automatically create joined tables based on collections. Not easy to determine many/many vs 1/many - but I have some ideas :).
To create a one to many relationship you just have to create the object model, SubSonic should do the rest for you e.g.
public class Shop
{
public int Id { get; set; }
public String Name { get; set; }
public List<Employee> Employees { get; set; }
}
public class Employee
{
public int Id { get; set; }
public String Name { get; set; }
}
EDIT: This should generate two tables when you run a migration not 3. The 3 three tables you describe in your question would represent a many to many relationship. Also in your example you're not saving your Employees, SubSonic does not cascade saves so you'll need to save your Shop then add the Employees to it and BatchSave the Employees.

Resources