I am running into a strange null pointer exception when attempting to create a sheet using ApachePOI. I require a more modular code as this is part of a larger system. I have been unable to find any similar examples online, all examples are stored within a main method.
I am also wondering when it is necessary to include a workbook.write(outputStream) does this need to be in every method that a new sheet/workbook/row/cell is created or only when I am writing data to the sheets (like in the write method)?
public class ExcelWriter {
private XSSFWorkbook workbook;
private String outputFile;
private ArrayList<XSSFSheet> sheets;
private static int sheetCount;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Constructor --> initializes a workbook
public ExcelWriter(String outputFile) throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
this.outputFile=outputFile;
sheets=new ArrayList<XSSFSheet>();
sheetCount=0;
FileOutputStream os = new FileOutputStream(outputFile);
workbook.write(os);
os.close();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Method to create a new sheet in the workbook, add to sheet list
public void newSheet(String sheetName) throws IOException {
sheets.add(workbook.createSheet(sheetName)); //ERROR HERE****
sheetCount++;
FileOutputStream os = new FileOutputStream(outputFile);
workbook.write(os);
os.close();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Method to write a cell into a worksheet given sheet row and column
public void write(int sheet,int row, int col, String data) {
XSSFSheet tempSheet=sheets.get(sheet);
System.out.println("yest");
// Specific row number
XSSFRow tempRow = tempSheet.createRow(row);
// Specific cell number
XSSFCell cell = tempRow.createCell(col);
// putting value at specific position
cell.setCellValue(data);
// writing the content to Workbook
OutputStream os;
try {
os = new FileOutputStream(outputFile);
workbook.write(os);
} catch (IOException e) {
e.printStackTrace();
}
}
Related
I have an objectlistview with 4 columns and a dynamic number of rows, I'm struggling with programmable editing a cell text value, and optionally change the forecolor
I've read everything and anything that I could put my hands on, but couldn't find any valid and right to the point example on how to do it.
the ObjectListView is created this why
List<VideoItem> list = new List<VideoItem>();
foreach (dynamic item in VideoItems)
{
list.Add(new VideoItem { Index = (int)item.index, OldName = (string)item.oldname, NewName = (string)item.newname });
}
olv1.AddObjects(list);
VideoItem class look like this
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
but i need to programmably edit a cell text on event. I'm doing some logical operations on other cell at the end im storing the result to to cell next to it.
You should be storing the result (making the change) to the underlying model object and then call RefreshObject(myModelObject);
About the forcolor, i need to change only the cell I've changed
"To change the formatting of an individual cell, you need to set UseCellFormatEvents to true and then listen for FormatCell events."
Take a look at this.
Just to add to Rev1.0 Answer, i needed to update the object that contains the items (in my case a List) then, use olv1.RefreshObject(list); flow by olv1.BuildList(true);
the olv1.BuildList(true); refresh the GUI immediately.
here a small code snippet to make thing bit more clear
it's changing the data in column 3 when a checkbox is checked.
using System.Collections.Generic;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Initializeolv();
}
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
private List<VideoItem> list = new List<VideoItem>();
private void Initializeolv()
{
for (var i = 1; i <= 10; i++)
{
list.Add(new VideoItem { Index = i, OldName = $"old{i}", NewName = $"new{i}" });
}
olv1.AddObjects(list);
}
private void olv1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
list[e.Item.Index].NewName = "new200";
olv1.RefreshObject(list);
olv1.BuildList(true);
}
}
}
I use the below code to go to next page. It works as expected but after that the
browser freezes. Does not retrieve any data from the next webpage.
http://www.forbes.com/companies/icbc/
public void test() throws InterruptedException {
Thread.sleep(10000);
for(int i=1;i<3;i++)
{
WebElement tab=driver.findElement(By.className("large"));
Thread.sleep(1000);
String text= tab.getText();
System.out.println(text);
String industry=driver.findElement(By.xpath("//*[contains(text(),'Industry')]//following::dd[1]")).getText();
System.out.println(industry);
Workbook workbook;
try
{
workbook = Workbook.getWorkbook(new File("D:\\Dummy.xls"));
WritableWorkbook copy = Workbook.createWorkbook(new File("D:\\Dummy.xls"),workbook);
WritableSheet sheet=copy.getSheet(0);
Label lable = new Label(0,i,industry);
sheet.addCell(lable);
copy.write();
copy.close();
}
catch (Exception e)
{
e.printStackTrace();
}
//WebElement nextPage=driver.findElement(By.className("next-number"));
WebElement nextPage=driver.findElement(By.xpath("//span[contains(#class, 'next-number')]"));
nextPage.click();
I am getting the error :
NoSuchWindowEception: Unable find element on a closed window
I'm using IE to automate the process.
I am running Automation test cases with #RunWith(CucumberWithSerenity.class).
We want to expose and maintain the Testdata separately in the Excel sheets instead of placing it in the Feature files.
The Template for Excel Testdata looks like:
|Scenario |UserName |Password|Name |Address|City |Pincode|
|Testcase1|testuser1|pass1 |testUser1|US |Jersy |12345 |
|Testcase1|testuser2|pass1 |testUser1|US |Virginia|78955 |
We have chose to use Primary Key as 'Scenario' which would be present in both Feature file and Excel sheet and based on that we will read the specific row from excel and refer the specific row data as Testdata for that particular Scenario.
Questions:
Is there a way to get the Scenario Name at run time from Feature file when Test is running, so that we can get the Excel sheet the extract the data for it from the Excel Sheets?
Is there a default way/method available in above mentioned use case, so that we can use it for above use case?
Cucumber doesn't support external sources by design (it is a collaboration tool, not a test automation tool). In Serenity, you can build a parameterised JUnit test that gets data from a CSV file: http://serenity-bdd.info/docs/serenity/#_using_test_data_from_csv_files
public class ExcelDataTable {
private XSSFWorkbook book;
private FileInputStream file;
public String ReadDataSheet(String page, String path, int rowValue, int cellValue) throws IOException {
String pointer;
file = new FileInputStream(new File(path));
book = new XSSFWorkbook(file);
Sheet sheet = book.getSheet(page);
Row row = sheet.getRow(rowValue);
Cell cell = row.getCell(cellValue);
pointer = cell.getStringCellValue();
book.close();
file.close();
return pointer;
}
}
Just create a class with this code and here is how I'm using it
public class OpenWebSite implements Task {
ExcelDataTable data = new ExcelDataTable();
public static OpenWebSite openWebSite(){
return Tasks.instrumented(OpenWebSite.class);
}
#Override
public <T extends Actor> void performAs(T actor) {
try {
actor.attemptsTo(Open.url(data.ReadDataSheet("info", "Data.xlsx", 1, 1)));
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Sort that out to make yours bro
I'm creating a GUI, and I use a method "getStudentInfo()" of the Student object return data type to retrieve information from the JTextFields and storing them into the "student" object.
public Student getStudentInfo() {
Student student = new Student();
String name = jtfName.getText();
student.setName(name);
String idNumber = jtfIDNumber.getText();
student.setIdNumber(idNumber);
String address = jtfAddress.getText();
student.setAddress(address);
String phoneNumber = jtfPhoneNumber.getText();
student.setPhoneNumber(phoneNumber);
String major = jtfMajor.getText();
student.setMajor(major);
return student;
}
Then, in a different class, I create an "Add" button that, when clicked, is supposed to add the "student" object into an ArrayList, and then write the ArrayList into a binary file.
private class AddButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
File studentFile = new File(FILENAME);
ArrayList<Student> studentList = new ArrayList<Student>();
studentList.add(text.getStudentInfo());
try {
FileOutputStream fos = new FileOutputStream(studentFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(studentList);
}
catch (FileNotFoundException fnf) {
fnf.printStackTrace();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
But when I run the program and I write a student's info and add it to the binary file, then I go to add another student, it overwrites the previous student's info completely. Any help would be greatly appreciated.
In the actionPerformed method of your class, AddButtonListener, you have the following line of code:
FileOutputStream fos = new FileOutputStream(studentFile);
This constructor will open the file so bytes are written to the beginning of your file. Since you reopen this file each time the button is clicked, you are replacing the file contents with new data. Instead, use the constructor with the boolean parameter for appending bytes rather than overwriting...
FileOutputStream fos = new FileOutputStream(studentFile, true);
You can check out this constructor's details in the java documentation...
FileOutputStream constructor documentation
I'm using Wicket (not sure if it matters) but I'm using Workbook to create an excel file for a user to download. But I'm not sure how exactly to do this. What I would like to happen is the user clicks the button, a log is created and a prompt is given to the user to open (and save to temp files) or to save to their computer. The file is then deleted from the server side, or maybe it is stored in the User's session and deleted at end of session.
Can someone point me in the right direction? If I can have the file not saved in the session at all, that'd be create and have it just have it sent to the client using FileOutputStream somehow..
here is my current code:
private void excelCreator()
{
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("SSA User ID " + currentSSAIDSelection2.getSsaUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream("ssaUserIDAccess.xls");
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
You would have to create a DownloadLink with the temporary file as input. The temporary File must be deleted after download (file.delete())).
Alternatively you can try this:
IResourceStream stream = new ByteArrayResourceStream(data, "application/vnd.ms-excel");
RequestCycle.get().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(stream, filename).setContentDisposition(ContentDisposition.ATTACHMENT));
In this case data is the byte[] content of your workbook which can be for example retrieved with output.toByteArray().
In case anyone runs into this problem here is my solution. There wasn't a lot of straight forward answers on this but this is my solution:
My excelCreator method handles the creation of the excel Sheet, and returns it as a file.
private File excelCreator()
{
Workbook workbook = new HSSFWorkbook();
File excelfile = new File("userIDAccess.xls");
logList = getServer().findAuditLogs(getUserId(), null);
Sheet sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("User ID " + getUserId()));
Iterator<AuditLogEntry> auditLogEntrys = logList.iterator();
int i = 0;
while (auditLogEntrys.hasNext())
{
final AuditLogEntry auditLogEntry = auditLogEntrys.next();
Row row = sheet.createRow(i);
row.createCell(0).setCellValue(auditLogEntry.getTimeStamp());
row.createCell(1).setCellValue(auditLogEntry.getSourceName());
row.createCell(2).setCellValue(auditLogEntry.getCategory());
row.createCell(3).setCellValue(auditLogEntry.getSsaAdmin());
row.createCell(4).setCellValue(auditLogEntry.getAction());
i++;
}
try
{
FileOutputStream output = new FileOutputStream(excelfile);
workbook.write(output);
output.close();
}catch(Exception e)
{
e.printStackTrace();
}
return excelfile;
}
IModel excelFileModel = new AbstractReadOnlyModel()
{
public Object getObject()
{
return excelCreator();
}
};
I created an IModel to capture the file created inside my excelCreator() method and returned.
auditDownloadlink = new DownloadLink("auditDownloadlink", excelFileModel);
I pass the I.D. of the download link, and then pass the imodel.
finally,
I call,
auditDownloadlink.setDeleteAfterDownload(true);
auditDownloadlink.setCacheDuration(Duration.NONE);
This deletes the file after it is created. And the cache setting is a setting to make sure it is compatible with all browsers (That's how I interpreted it, but you may not need it).
The Imodel creates the File on the fly so it doesn't have to be stored anywhere, and then the file is deleted once it is downloaded.
Hope this helps someone!
You could create a Resource to do this, and make a ResourceLink.
public class ExcelProducerResource extends AbstractResource
{
public ExcelProducerResource()
{
}
#Override
protected ResourceResponse newResourceResponse( Attributes attributes )
{
final String fileName = getFileName();
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
resourceResponse.setCacheDuration( Duration.NONE );
resourceResponse.setFileName( fileName );
resourceResponse.setWriteCallback( new WriteCallback()
{
#Override
public void writeData( Attributes attributes ) throws IOException
{
OutputStream outputStream = attributes.getResponse().getOutputStream();
writeToStream( outputStream );
outputStream.close();
}
} );
return resourceResponse;
}
void writeToStream(OutputStream outputStream) throws IOException
{
//.. do stuff here :)
}
String getFileName()
{
//.. do stuff here :)
}
}