I've tried using Jexcel
to update an existing excel sheet as discussed in the Vogella tutorial.
Issue here is the data already present in the existing excel sheet is wiped out with the newly written excel data.
For example if I've this in the excel
<table>
<tr>
<td>1</td> <td>2 </td>
</tr>
<tr>
<td>3</td> <td>4 </td>
</tr>
<table>
and I want to add data to the new cell next to 2 and 4, like
<table>
<tr>
<td>1</td> <td>2 </td> <td>X </td>
</tr>
<tr>
<td>3</td> <td>4 </td> <td>Y </td>
</tr>
<table>
after the write program executed this is what I get
<table>
<tr>
<td> </td> <td> </td> <td>X </td>
</tr>
<tr>
<td> </td> <td> </td> <td>Y </td>
</tr>
<table>
Label label;
label = new Label(column, row, s, times);
sheet.addCell(label);
This is adding the cell at the specified column and row but wiping out the rest of the excel data.
How can I add data to the existing excel keeping the data?
Following is the program(Reference: Vogella). Excel sheet already has data in 20 rows and
first 2 columns, am trying to add data on the 3rd column for 20 rows
package excel;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import jxl.CellView;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
public class WriteExcel {
private WritableCellFormat timesBoldUnderline;
private WritableCellFormat times;
private String inputFile;
public void setOutputFile(String inputFile) {
this.inputFile = inputFile;
}
public void write() throws IOException, WriteException {
File file = new File(inputFile);
WorkbookSettings wbSettings = new WorkbookSettings();
wbSettings.setLocale(new Locale("en", "EN"));
WritableWorkbook workbook = Workbook.createWorkbook(file, wbSettings);
workbook.createSheet("Report", 0);
WritableSheet excelSheet = workbook.getSheet(0);
createLabel(excelSheet);
createContent(excelSheet);
workbook.write();
workbook.close();
}
private void createLabel(WritableSheet sheet) throws WriteException {
// Lets create a times font
WritableFont times10pt = new WritableFont(WritableFont.TIMES, 10);
// Define the cell format
times = new WritableCellFormat(times10pt);
// Lets automatically wrap the cells
times.setWrap(true);
// Create create a bold font with unterlines
WritableFont times10ptBoldUnderline = new WritableFont(
WritableFont.TIMES, 10, WritableFont.BOLD, false,
UnderlineStyle.SINGLE);
timesBoldUnderline = new WritableCellFormat(times10ptBoldUnderline);
// Lets automatically wrap the cells
timesBoldUnderline.setWrap(true);
CellView cv = new CellView();
cv.setFormat(times);
cv.setFormat(timesBoldUnderline);
cv.setAutosize(true);
}
private void createContent(WritableSheet sheet) throws WriteException,
RowsExceededException {
Integer salary = 1000;
// Now a bit of text
for (int i = 0; i < 20; i++) {
// third column
addLabel(sheet, 2, i, salary.toString());
// WritableCell cell = sheet.getWritableCell(2, i);
// if (cell.getType() == CellType.LABEL) {
// Label l = (Label) cell;
// l.setString("modified cell");
// }
salary += 1000;
}
}
private void addLabel(WritableSheet sheet, int column, int row, String s)
throws WriteException, RowsExceededException {
Label label;
label = new Label(column, row, s, times);
sheet.addCell(label);
}
public static void main(String[] args) throws WriteException, IOException {
WriteExcel test = new WriteExcel();
test.setOutputFile("c:/temp/lars.xls");
test.write();
System.out
.println("Please check the result file under c:/temp/lars.xls ");
}
}
You are using WritableWorkbook which creates a NEW writable work book over writing the previous one. To modify the existing workbook you will first have to create a copy of the existing workbook something like below :
Workbook workbook = Workbook.getWorkbook(new File("myfile.xls"));
WritableWorkbook copy = Workbook.createWorkbook(new File("output.xls"), workbook);
and then work on the copy. For more detailed info see (Path where you have extracted the api)\jexcelapi\src\jxl\demo\ReadWrite.java or navigate to Copying and Modifying Spreadsheets of this page.
Related
I want to make quick search in the JSF page before I submit the form (partial update) , so I have two values, one is input text and I want the result show in the output text when the user enter the value in the input text. for example I want to search about the name of the user using the user id, so in the input text the user will enter the user id (e.g 2323) then the search will happens and this will render the output text with the name of this user(2323).
I use a4j:support in order to achieve this but nothing shown with me and there is no any error or exception.
this is my JsF page:
<tr>
<td>
<table>
<tr>
<td width="80px"><h:outputLabel
value="user id"></h:outputLabel></td>
<td width="5px"> </td>
<td><h:inputText id="secondIdNum" maxlength="6" style="width:240px"
value="#{ideaDetailsBean.addIdeaDto.secondId}">
<a4j:support event="onchanged" actionListener="#
{ideaDetailsBean.secondIdChange}"
reRender="secondNameId" />
</h:inputText></td>
<td width="15px"> </td>
<td width="80px"><h:outputLabel value="user name "></h:outputLabel></td>
<td width="5px"> </td>
<td><h:outputText id="secondNameId"
style="width:240px"
value="#{ideaDetailsBean.addIdeaDto.secondName}"></h:outputText>
</td>
</tr>
</table>
</td>
</tr>
in the backbean:
public void secondIdChange(ActionEvent actionEvent) {
if(addIdeaDto.getSecondId() != null){
addIdeaDto.setSecondName(getParticipantName(addIdeaDto.getSecondId()));
}
}
static String getParticipantName(String employeeId) {
IIMDelegate iimDelegate = new IIMDelegate();
UserInfoDto userInfoDto = new UserInfoDto();
iimDelegate.getParticipant(employeeId);
return userInfoDto.getUserName();
}
in the DAO:
public UserInfoDto getParticipant(String employeeId) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet searchResultSet = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(
"SELECT U_NAME FROM APPL_USER WHERE U_LOGIN = ?");
// Assign first value to first parameter
preparedStatement.setString(1, employeeId);
searchResultSet = preparedStatement.executeQuery();
return getParticipant(searchResultSet);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
searchResultSet.close();
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
private UserInfoDto getParticipant(ResultSet searchResultSet) throws SQLException {
List<UserInfoDto> result = new ArrayList<UserInfoDto>();
UserInfoDto userInfoDto = null;
while (searchResultSet.next()) {
userInfoDto = new UserInfoDto();
userInfoDto.setUserName(searchResultSet.getString(1));
result.add(userInfoDto);
}
return result == null ? null : result.size() > 0 ? result.get(0) :null;
}
Any suggestion to achieve this in different way?
Anyone have experience working with a complex model and RazorEngine?
Working on generating HTML using RazorEngine version 3.7.3, but running into issues with the complex model view we have. It seems like we should be able to use the templates to get RazorEngine to discover the SubSample below, but have not discovered the proper way to tell RazorEngine about the associated cshtml file.
In the example below we are looking to use a shared template for the SubSample class using the SubSample.cshtml file. As can be seen from the results, the class namespace (ReportSample.SubSample) is displayed rather than an HTML row of data.
We have tried implementing an ITemplateManager, but Resolve() is never called with a key asking for the SubSample. Also tried AddTemplate() on the service, but still no joy.
Here is a simplified example model to illustrate the issue:
namespace ReportSample
{
public class SubSample
{
public string Name { get; set; }
public string Value { get; set; }
}
public class SampleModel
{
public SubSample SubSample { get; set; }
}
}
SampleModel.cshtml
#using ReportSample
#*#model ReportSample.SampleModel*#
<table style="width: 7.5in" align="center">
<tr>
<td align="center">
<h1>
Sample Report
</h1>
</td>
</tr>
<tr>
<td>
<table style="width: 100%">
<tr>
<td colspan="2">
<b>Name:</b> #Model.SubSample.Name
</td>
<td colspan="2">
<b>Value:</b> #Model.SubSample.Value
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td align="center">
<h1>
Sub-sample Data
</h1>
</td>
<td>
<table style="width: 100%">
#Model.SubSample
</table>
</td>
</tr>
</table>
SubSample.cshtml
#model ReportSample.SubSample
#using FSWebportal.Infrastructure.Mvc;
<tr class="observation-row">
<td class="observation-label">
#model.Name
</td>
<td class="observation-view">
#model.Value
</td>
</tr>
Basic RazorEngine calls:
private void html_Click(object sender, EventArgs e)
{
var gen = new RazorEngineGenerator();
var cshtmlTemplate = File.ReadAllText("Sample.cshtml");
var sample = new SampleModel() { SubSample = new SubSample() { Name = "name", Value = "value" } };
var html = gen.GenerateHtml(sample, cshtmlTemplate);
}
public string GenerateHtml<T>(T model, string cshtmlTemplate)
{
var config = new TemplateServiceConfiguration();
using (var service = RazorEngineService.Create(config))
{
return service.RunCompile(cshtmlTemplate, "", typeof(T), model);
}
}
Sample HTML Output:
Sample Report
Name: name
Value: value
Sub-sample Data
ReportSample.SubSample
I'm sorry but I don't think I fully understand your question but I have a small idea of what you are trying to do...
I think what you want are searching for are partial templates (using #Include)!
using RazorEngine;
using RazorEngine.Templating;
using System;
namespace TestRunnerHelper
{
public class SubModel
{
public string SubModelProperty { get; set; }
}
public class MyModel
{
public string ModelProperty { get; set; }
public SubModel SubModel { get; set; }
}
class Program
{
static void Main(string[] args)
{
var service = Engine.Razor;
// In this example I'm using the default configuration, but you should choose a different template manager: http://antaris.github.io/RazorEngine/TemplateManager.html
service.AddTemplate("part", #"my template");
// If you leave the second and third parameters out the current model will be used.
// If you leave the third we assume the template can be used for multiple types and use "dynamic".
// If the second parameter is null (which is default) the third parameter is ignored.
// To workaround in the case you want to specify type "dynamic" without specifying a model use Include("p", new object(), null)
service.AddTemplate("template", #"<h1>#Include(""part"", #Model.SubModel, typeof(TestRunnerHelper.SubModel))</h1>");
service.Compile("template", typeof(MyModel));
service.Compile("part", typeof(SubModel));
var result = service.Run("template", typeof(MyModel), new MyModel { ModelProperty = "model", SubModel = new SubModel { SubModelProperty = "submodel"} });
Console.WriteLine("Result is: {0}", result);
}
}
}
I have added documentation for this here: https://antaris.github.io/RazorEngine/LayoutAndPartial.html
However I think making #Model.SubSample work is possible as well, you can either change the SubSample property to be of type TemplateWriter or make the SubSample class implement IEncodedString. But I think you should consider partial templates first!
i have been trying to trying to implement something like
<< < (textbox) of (totalnumberofpages) > >>
any suggestions on this
Thanks in advance...
If you are looking for pagination in DataView then ,all you need to do to enable paging is to call setItemsPerPage(int) on the dataview.
Check following example JAVA code
public class RepeatingPage extends BasePage
{
private static final long serialVersionUID = 1L;
/**
* Constructor
*/
public RepeatingPage()
{
Iterator<Contact> contacts = new ContactDataProvider().iterator(0, 10);
RepeatingView repeating = new RepeatingView("repeating");
add(repeating);
int index = 0;
while (contacts.hasNext())
{
AbstractItem item = new AbstractItem(repeating.newChildId());
repeating.add(item);
Contact contact = contacts.next();
item.add(new ActionPanel("actions", new DetachableContactModel(contact)));
item.add(new Label("contactid", String.valueOf(contact.getId())));
item.add(new Label("firstname", contact.getFirstName()));
item.add(new Label("lastname", contact.getLastName()));
item.add(new Label("homephone", contact.getHomePhone()));
item.add(new Label("cellphone", contact.getCellPhone()));
final int idx = index;
item.add(AttributeModifier.replace("class", new AbstractReadOnlyModel<String>()
{
private static final long serialVersionUID = 1L;
#Override
public String getObject()
{
return (idx % 2 == 1) ? "even" : "odd";
}
}));
index++;
}
}
}
HTML code
<wicket:extend xmlns:wicket="http://wicket.apache.org">
<br/><br/>
<table cellspacing="0" class="dataview">
<tr>
<th>Actions</th>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Home Phone</th>
<th>Cell Phone</th>
</tr>
<tr wicket:id="repeating">
<td><span wicket:id="actions">[actions]</span></td>
<td><span wicket:id="contactid">[contactid]</span> </td>
<td><span wicket:id="firstname">[firstname]</span></td>
<td><span wicket:id="lastname">[lastname]</span></td>
<td><span wicket:id="homephone">[homephone]</span></td>
<td><span wicket:id="cellphone">[cellphone]</span></td>
</tr>
</table>
</wicket:extend>
If you need pagination in listView then check for PageableListView
I have the following xml that i need to transfom to an other form. I have a C# code that does it but it has a bug with is hard to track. I beleive Linq could offer a more error prone way to do this.
input xml:
<NewDataSet>
<Table>
<RoleId>5</RoleId>
<Code>DP</Code>
<Description>Process data</Description>
<Task>Validate indices</Task>
<TaskId>12</TaskId>
<Country>BE</Country>
<CountryId>3</CountryId>
</Table>
<Table>
<RoleId>5</RoleId>
<Code>DP</Code>
<Description>Process data</Description>
<Task>calculate indices</Task>
<TaskId>11</TaskId>
<Country>US</Country>
<CountryId>4</CountryId>
</Table>
<Table>
<RoleId>5</RoleId>
<Code>DP</Code>
<Description>Process data</Description>
<Task>Calculate indices</Task>
<TaskId>11</TaskId>
<Country>UK</Country>
<CountryId>5</CountryId>
</Table>
<Table>
<RoleId>1</RoleId>
<Code>DR</Code>
<Description>View data</Description>
<Task>View Reports</Task>
<TaskId>9</TaskId>
<Country>SC</Country>
<CountryId>17</CountryId>
</Table>
<Table>
<RoleId>1</RoleId>
<Code>DR</Code>
<Description>View data</Description>
<Task>View Basics</Task>
<TaskId>10</TaskId>
<Country>SC</Country>
<CountryId>17</CountryId>
</Table>
<Table>
<RoleId>1</RoleId>
<Code>DR</Code>
<Description>View data</Description>
<Task>Download data</Task>
<TaskId>11</TaskId>
<Country>FR</Country>
<CountryId>15</CountryId>
</Table>
</NewDataSet>
and the output that i need is as follow:
<NewDataSet>
<Table>
<RoleId>5</RoleId>
<Code>DP</Code>
<Description>Process data</Description>
<Task>Validate indices,Calculate indices,</Task>
<TaskId>12,11</TaskId>
<Country>BE,US,UK</Country>
<CountryId>3,4,5</CountryId>
</Table>
<Table>
<RoleId>1</RoleId>
<Code>DR</Code>
<Description>Process data from commercial fisheries</Description>
<Task>View Reports,View Basics,View data</Task>
<TaskId>9,10,11</TaskId>
<Country>SC,FR</Country>
<CountryId>17,15</CountryId>
</Table>
</NewDataSet>
As you can see, the elements are group by RoleId, Code and Description.
I have created a custum object to project the xml element to
public class Table
{
public int RoleId {get;set;}
public string Code {get;set;}
public string Description {get;set;}
public string Task {get;set;}
public int TaskId {get;set;}
public string Country {get;set;}
public int CountryId {get;set;}
}
The idea is then to use this list of custum object to recreate an xml document. But i was thinking there could be a more straigforward way. without the need to use the custum object list.
The rest of the element are simply concatenated. I hope someone have an idea sugestion of how this could be achieved using Linq to XML.
many thanks in advance
var doc = XDocument.Load("Input.txt");
var tables = from t in doc.Root.Elements("Table")
select new Table
{
RoleId = (int)t.Element("RoleId"),
Code = (string)t.Element("Code"),
Description = (string)t.Element("Description"),
Task = (string)t.Element("Task"),
TaskId = (int)t.Element("TaskId"),
Country = (string)t.Element("Country"),
CountryId = (int)t.Element("CountryId")
};
var groups = tables.GroupBy(x => new { x.RoleId, x.Code, x.Description });
var resultDoc = new XDocument(
new XElement("NewDataSet",
from g in groups
select new XElement("Table",
new XElement("RoleID", g.Key.RoleId),
new XElement("Code", g.Key.Code),
new XElement("Description", g.Key.Description),
new XElement("Task", string.Join(",", g.Select(x => x.Task))),
new XElement("TaskId", string.Join(",", g.Select(x => x.TaskId.ToString()))),
new XElement("Country", string.Join(",", g.Select(x => x.Country))),
new XElement("CountryId", string.Join(",", g.Select(x => x.CountryId.ToString()))))));
It's fully LINQ to XML solution, although you should consider changing the parsing part with XML Serialization.
Result XML:
<NewDataSet>
<Table>
<RoleID>5</RoleID>
<Code>DP</Code>
<Description>Process data</Description>
<Task>Validate indices,calculate indices,Calculate indices</Task>
<TaskId>12,11,11</TaskId>
<Country>BE,US,UK</Country>
<CountryId>3,4,5</CountryId>
</Table>
<Table>
<RoleID>1</RoleID>
<Code>Data Reader</Code>
<Description>View data</Description>
<Task>View Reports,View Basics,Download data</Task>
<TaskId>9,10,11</TaskId>
<Country>SC,SC,FR</Country>
<CountryId>17,17,15</CountryId>
</Table>
</NewDataSet>
I'm in the middle of making an ASP .NET MVC4 based app. I'm a complete newb in that field. The idea is quite simple - have a some members in DB, show them listed, select desired ones via check boxes and redirect to some other controller which would do something with the previously selected members.
Problem is passing the list of members from View to the Controller. I've thought it would work with ViewModel. It certainly works from Controller to the View, but not the other way.
My ViewModel:
public class MembersViewModel
{
public IEnumerable<Directory_MVC.Models.Member> MembersEnum { get; set; }
public string Test { get; set; }
}
Snippet of my Controller:
public class MembersController : Controller
{
private MainDBContext db = new MainDBContext();
public ActionResult Index()
{
var model = new Directory_MVC.ViewModels.MembersViewModel();
// populating from DB
model.MembersEnum = db.Members.Include(m => m.Group).Include(m => m.Mother).Include(m => m.Father);
model.Test = "abc";
return View(model);
}
[HttpPost]
public ActionResult GoToSendEmail(Directory_MVC.ViewModels.MembersViewModel returnedStruct)
{
if (ModelState.IsValid)
{
// it is valid here
return Redirect("http:\\google.com");
}
}
Snippet of my View:
#model Directory_MVC.ViewModels.MembersViewModel
#{
ViewBag.Title = "Members listing";
var lineCount = 0;
string lineStyle;
}
#using (Html.BeginForm("GoToSendEmail", "Members", FormMethod.Post))
{
<table>
#foreach (var item in Model.MembersEnum)
{
lineCount++;
// set styling
if (lineCount % 2 == 1)
{
lineStyle = "odd-line";
}
else
{
lineStyle = "even-line";
}
<tr class="#lineStyle">
<td>
#Html.EditorFor(modelItem => item.Selected)
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Mother.FirstName) #Html.DisplayFor(modelItem => item.Mother.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Father.FirstName) #Html.DisplayFor(modelItem => item.Father.LastName)
</td>
<!-- other print-outs but not all properties of Member or Mother/father are printed -->
</tr>
}
</table>
<input type="submit" value="Send E-mail" />
}
The data are shown OK in the View. However, when I submit that form the returnedStruct.MembersEnum and Test string are both null in the Controller's method GoToSendEmail.
Is there a mistake or is there another possible way how to pass that members structure and check their Selected property?
Model binding to a collection works a little differently. Each item has to have an identifier so that inputs don't all have the same name. I've answered a similar question here.
#for (int i = 0; i < Model.MembersEnum.Count(); i++)
{
#Html.EditorFor(modelItem => modelItem.MembersEnum[i].FirstName)
}
...which should render something like...
<input type="text" name="MembersEnum[0].FirstName" value="" />
<input type="text" name="MembersEnum[1].FirstName" value="" />
<input type="text" name="MembersEnum[2].FirstName" value="" />
...which should then populate the collection in your ViewModel when picked up by the controller...
public ActionResult GoToSendEmail(ViewModels.MembersViewModel model)
As mentioned in the other answer, I'd have a look at some related articles from Scott Hansleman and Phil Haack.
You also mentioned that your string called Test is null when you submit to your POST action. You haven't added a field for this property anywhere within your form, so there's nothing for the model binder to bind to. If you add a field for it within your form then you should see the value in the POST action:
#Html.EditorFor(modelItem => modelItem.Test)
Html.BeginCollectionItem() helper did the job - BeginCollectionItem.