How to write an excel table starting from the last value? - java

I am using JXL api. I want to fill an excel table that already have content, like:
123 321 12324
123 321 231
123 321 343
123 321 454
123 321 565
I am trying to write the next value after the fifth line, but I dont know how to do it. I only know how to create and write an excel table if it is empty. And I know how to read it. I was thinking that first I have to read it, and my array which would contain the values of the table would help me to pick the last value of the table then I would write the other values starting from there. I have these methods:
To read:
arquivo = new File("C:\\Users\\maniceto\\Desktop\\arq.xls");
planilha = Workbook.getWorkbook(arquivo);
Sheet[] abas = planilha.getSheets();
aba = planilha.getSheet(0);
matriz = new String[aba.getRows()][aba.getColumns()];
Cell[] cel;
for (int i = 0; i < matriz.length; i++) {
cel = aba.getRow(i);
for (int j = 0; j < matriz[0].length; j++) {
matriz[i][j] = cel[j].getContents();
}
}
System.out.println("Lines " + matriz.length);
System.out.println("Columns " + matriz[0].length);
System.out.println("");
for (int i = 0; i < matriz.length; i++) {
for (int j = 0; j < matriz[0].length; j++) {
System.out.print(matriz[i][j] + "\t");
}
System.out.println("");
}
To write an empty excel table:
WritableWorkbook workbookVazio = Workbook.createWorkbook(file);
WritableSheet sheet1 = workbookVazio.createSheet("First Sheet", 0);
TableModel model = table.getModel();
for (int i = 0; i < model.getColumnCount(); i++) {
Label column = new Label(i, 0, model.getColumnName(i));
sheet1.addCell(column);
}
int j = 0;
for (int i = 0; i < model.getRowCount(); i++) {
for (j = 0; j < model.getColumnCount(); j++) {
Label row = new Label(j, i + 1,
model.getValueAt(i, j).toString());
sheet1.addCell(row);
}
}
workbookVazio.write();
workbookVazio.close();

As stated by rgettman in this question, I would also advise to use Apache POI to handle Excel files with JAVA.
To append values using POI, you just need to get the current number of rows :
int rows = sheet.getPhysicalNumberOfRows();
POI is well documented and you will easily find several code examples on the net.

you could try something like
int lastRowNum = workbookVazio.getSheet("First Sheet").getLastRowNum();
int nextFreeRow = lastRowNum+1;
or you can use Apache POI theres a good tutorial here.

Related

How to align output from an excel file?

''''Workbook wb = new Workbook("workbook.xlsx");
WorksheetCollection collection = wb.getWorksheets();
for (int worksheetIndex = 0; worksheetIndex < collection.getCount(); worksheetIndex++) {
Worksheet worksheet = collection.get(worksheetIndex);
System.out.println("People on Island: " + worksheet.getName());
System.out.println();
int rows = worksheet.getCells().getMaxDataRow();
int cols = worksheet.getCells().getMaxDataColumn();
Style st = wb.createStyle();
for (int i = 0; i <= rows; i++) {
for (int j = 0; j <= cols; j++) {
System.out.print(worksheet.getCells().get(i, j).getValue() + " ");
}
System.out.println();
System.out.println();
}
}
}''''
OUTPUT CURRENTLY:
People on Island: Sheet1
First Name Last name Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00
You can do something like this:
//Code for reading data, not relevant for the solution
String my_string= """
People on Island: Sheet1
FirstName LastName Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00""";
String[] split_string = my_string.split("\n\n");
String[][] finalString = new String[split_string.length][];
for (int i = 0; i < split_string.length; i++) {
finalString[i] = split_string[i].split(" ");
}
//Relevant code below
int spaceBetween = 25; //this variable decides the distance between each column
for (int i = 0; i < finalString.length; i++) {
for (int j = 0; j < finalString[i].length; j++) {
System.out.print(finalString[i][j]);
for (int k = 0; k < spaceBetween-finalString[i][j].length(); k++)
System.out.print(" ");
}
System.out.println("\n");
}
The output is:
People on Island: Sheet1
FirstName LastName Gender Country Age Date
Dulce Bleoop Female Zimbabwe 43 2035-03-01T00:00:00
Sheeba Loadlee Female Sketchawan 24 3040-04-03T00:00:00
Jello Bamop Male Antarctica 32 2053-04-06T00:00:00
Barbara Slack Female Scandalousia 70 3203-03-12T00:00:00
The Space between each column is decided by the variable spaceBetween.
In conclusion, you should be able to change the line
System.out.print(worksheet.getCells().get(i, j).getValue() + " ");
to
val = worksheet.getCells().get(i, j).getValue();
System.out.print(val);
for (int k = 0; k < spaceBetween-val.lenght(); k++)
System.out.print(" ");
where you choose a value for spaceBetween somewhere in the code.
If what you want is to align the output lines printed in console, you will have to loop over the fields two times. The first for getting whe length of each column and the second to print them correctly.
You can use a method that given a String pads it with whitespaces to the end:
public static String alignLeft(String str, int width) {
if (str.length() >= width) {
return str;
}
return alignLeft(str + " ", width);
}
Then, given the values of each cell as a String in a bidimensional array cells, doing the following:
int[] columnsWidths = new int[cells[0].length];
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
if (columnsWidths[j] < cells[i][j].length()) {
columnsWidths[j] = cells[i][j].length();
}
}
}
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
System.out.print(alignLeft(cells[i][j], columnsWidths[j]) + " ");
}
System.out.println();
}
Assuming you are using aspose, since you included the tag, you could use the export to array method:
....
int rows = worksheet.getCells().getMaxDataRow();
int cols = worksheet.getCells().getMaxDataColumn();
Object dataTable[][] = worksheet.getCells().exportArray(0, 0, rows, cols);
for (final Object[] row : dataTable) {
System.out.format("%15s%15s%15s%15s%15s%15s%n", row);
}
For left-aligned output change the print statement to
System.out.format("%-15s%-15s%-15s%-15s%-15s%-15s%n", row);
Of course 15 is just a random value I choosed, because I thought the max length of a cell value has 15 chars. change as you see fit. You could also for each column, check length of all strings in that column and take max string length in that column as column width for that column. Which could end for example in something like:
System.out.format("%-10s%-10s%-8s%-15s%-5s%-25s%n", row);

Read excel and Assign cell Value by column to an array

Using apache.poi, I am trying to read an Excel sheet and using the below code, I am printing all the values inside Excel..
for (int i = 0; i < rowCount + 1; i++) {
Row row = searcsheet.getRow(i);
// Create a loop to print cell values in a row
for (int j = 0; j < row.getLastCellNum(); j++) {
// Print Excel data in console
String location = (row.getCell(j).getStringCellValue()+ "");
System.out.println(location);
}
When I print the location System.out.println(location);, it prints my all Excel sheet data. I haven't any control over there. I am trying divide the value by the column.
Suppose I have 3 cells and I want to get a value like firstname[],lastname[],age[] so that I can do any operation by the indexing. I am not getting any solution.
Here is my full code
https://codeshare.io/anNwy3
Create a 2D String array. When iterating store the contents into the array
String[][] excelData = new String[numColumns][searcsheet.getLastRowNum()];
//numColumns is the number of columns in the excel sheet.
for (int i = 0; i < rowCount + 1; i++) {
Row row = searcsheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) {
String data = (row.getCell(j).getStringCellValue()+ "");
excelData[j][i] = data;
}
}
This transpose data when storing it into the array (note: excelData[j][i] and not excelData[i][j]).
With this, you can get all the contents of the first column as excelData[0].

apache POI merge cells with data resulting in data loss

We are displaying a number and a percent like "2 (100%)" in each cell.
I would like to apply different formatting to the Number part and percentage part. It seems not possible to apply different formatting, within a cell.
So I'm trying to write data into 2 consecutive cells, which have different formatting and then merge it.
But after merging , the data in the second cell is lost.
How can I merge, with both cells data merged to single cell ?
HSSFFont percentFont = wb.createFont();
percentFont.setFontName(HSSFFont.FONT_ARIAL);
percentFont.setFontHeightInPoints((short) 10);
percentFont.setBold(true);
percentStyle.setFont(percentFont);
for (int i = 0; i < rows.size(); i++) {
List<String> rowData = rows.get(i);
int rowNumber = 9 + i;
HSSFRow row1 = sheet.createRow(rowNumber);
int colNumber = 0;
for (int j = 0; j < count; j++) {
HSSFCell hssfMainCell = row1.createCell(colNumber);
HSSFCell hssfPercentCell = row1.createCell(colNumber + 1);
hssfPercentCell.setCellStyle(percentStyle);
String val = rowData.get(j);
String percentage = "(" + rowData.get(percentageColumns.get(j)) + "%)";
;
hssfMainCell.setCellValue(val);
hssfMainCell.setCellStyle(rightAligned);
if (percentageColumns.get(j) != null) {
hssfPercentCell.setCellValue(percentage);
percentStyle.setAlignment(CellStyle.ALIGN_RIGHT);
hssfPercentCell.setCellStyle(percentStyle);
sheet.addMergedRegion(new CellRangeAddress(rowNumber, rowNumber, colNumber, colNumber + 1));
colNumber++;
colNumber++;
}
}
}

printing data columnwise in same workbook - java poi

I am using Java and POI to print some data to excel files. I think I am just missing a small logic to solve this question. I have data stored in array lists in following format:
a = [1,2,3] // arraylist
b = [4,5,6] // arraylist
c = [7,8,9] // arraylist
I want to print this data columnwise to excel file in below given format:
1 | 4 | 7
2 | 5 | 8
3 | 6 | 9
The code that I am using is as below:
public final_out = new FileOutputStream(new File(final_output_path));
public XSSFWorkbook workbook = new XSSFWorkbook();
public XSSFSheet sheet = workbook.createSheet("data_vertical_final");
public Row row;
for (int i=0; i < a.size(); i++) {
String value = a.get(i);
row = sheet.createRow(i);
Cell cell = row.createCell(13);
cell.setCellValue(value);
}
for (int i=0; i < b.size(); i++) {
String value = b.get(i);
row = sheet.createRow(i);
Cell cell = row.createCell(15);
cell.setCellValue(value);
}
for (int i=0; i < c.size(); i++) {
String value = a.get(i);
row = sheet.createRow(i);
Cell cell = row.createCell(17);
cell.setCellValue(value);
}
workbook.write(final_out);
workbook.close();
final_out.close();
Error I am getting:
There is no error, but everything is getting overwritten in new excel file and the final output looks broken. Do I need to make new workbooks for every loop? or there is something I am missing.
P.S:
The data that is shown below is just an example. Some of my original files that I am using are between 1000 to 2000 values or maybe more.
I want to dynamically create the rows and extract the values from arraylists and store it in rows that I created.
Create only a.size() rows,
not a.size() squared rows.
Don't overwrite them in your code.
I assume that a.size() == b.size() and b.size() == c.size().
public List<Row> rows = new ArrayList<Row>(a.size());
for (int i=0; i < a.size(); i++) {
rows.add(sheet.createRow(i));
}
for (int i=0; i < a.size(); i++) {
String value = a.get(i);
Cell cell = rows.get(i).createCell(13);
cell.setCellValue(value);
}
for (int i=0; i < b.size(); i++) {
String value = b.get(i);
Cell cell = rows.get(i).createCell(15);
cell.setCellValue(value);
}
for (int i=0; i < c.size(); i++) {
String value = a.get(i);
Cell cell = rows.get(i).createCell(17);
cell.setCellValue(value);
}
If you already solve the problem:
It would be even cleaner to place a, b and c into one collection and use only one loop to iterate through them (in place of 3 separate loops).
I assume that a is the longest list.
Check this out:
public List<Row> rows = new ArrayList<>(a.size());
for (int i=0; i < a.size(); i++) {
rows.add(sheet.createRow(i));
}
List<List<String>> alphabet = new ArrayList<>();
alphabet.add(a);
alphabet.add(b);
alphabet.add(c);
for(int i=0; i < alphabet.size(); i++) {
for (int j=0; j < alphabet.get(i).size(); j++) {
String value = alphabet.get(i).get(j);
Cell cell = rows.get(j).createCell(13 + i*2); //<- 13, 15, 17...
cell.setCellValue(value);
}
}

Put two arrays to Jtable rows

I have two arrays, which is equal in terms of number of elements. I want to put it in a JTable rows (like in the ascii table example from bellow). I'm using table model and a loop for both arrays, but I archive something else (see print screen).
Note: I want to maintain the correspondence between elements of both arrays, like in the ascii table example.
Integer[] intArray = new Integer[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
intArray[i] = Integer.parseInt(stringArray[i]);
}
System.out.println(Arrays.toString(intArray)); //output [285, 715, 1437, 1749]
Integer[] intArray1 = new Integer[stringArray1.length];
for (int i = 0; i < stringArray1.length; i++) {
intArray1[i] = Integer.parseInt(stringArray1[i]);
}
System.out.println(Arrays.toString(intArray1)); //output [0, 0, 1087, 0]
DefaultTableModel modelPeaks = new DefaultTableModel();
JTable table = new JTable(modelPeaks);
modelPeaks.addColumn("1st Column");
modelPeaks.addColumn("2nd Column");
for (int i = 0; i < intArray.length; i++) {
for (int j = 0; j < intArray1.length; j++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[j]});
}
}
The output is:
But I want to archive this:
+--------------------+--------------------+
+ 1st Column + 2nd Column +
+--------------------+--------------------+
+ 285 + 0 +
+ 715 + 0 +
+ 1437 + 1087 +
+ 1749 + 0 +
+--------------------+--------------------+
I think that is from the loop, but I can't figure out how to fix it. Someone can help me? And thanks in advance for your time.
The last loop should read
for (int i = 0; i < intArray.length; i++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[i]});
}
Always make sure that both array have the same length.
If the arrays are both the same length you can use the same iterator for both:
for (int i = 0; i < intArray.length; i++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[i]});
}

Categories