How to align output from an excel file? - java

''''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);

Related

Beginner 2D-Array out of bounds exception

I'm having some difficulties trying to figure out how to implement a second array to calculate the averages of my marks program.
I'm using 1 2D array to store the scores each student received on each assignment
(5 students, 4 assignments).
I have managed to get the Students average array working but when I go to calculate each individual assignment mark (combined total of the 5 students /5 ). I keep getting an Indexoutofbounds exception, Im very new to 2d arays and am still trying to figure out how to read them properly.
Heres my code:
import java.util.Scanner;
public class Marks
{
private String[] names;
private int[][] assignments;
private double[] stuAvgArray;
private double[] assignAvgArray;
public Marks()
{
names = new String[5];
assignments = new int[5][4];
stuAvgArray = new double[5];
assignAvgArray = new double[4];
}
public void getInput()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter 5 student names: ");
for(int i = 0; i < names.length; i++)
names[i] = input.nextLine();
for(int row = 0; row < assignments.length; row++)
{
System.out.println("Enter the 4 marks for: " + names[row]);
for(int col = 0; col < assignments[row].length; col++)
{
assignments[row][col] = input.nextInt();
stuAvgArray[row] += assignments[row][col];
}
stuAvgArray[row] = (stuAvgArray[row]/4);
}
for (int col = 0; col < assignments.length; col++)
{
for(int row = 0; row < assignments[col].length; row++)
assignAvgArray[row] += assignments[row][col];
assignAvgArray[col] = (assignAvgArray[col]/5);
}
}
public String toString()
{
String output = ("Student \t\t\t Marks \t\t\t\t Average \n" +
"Name \t\t\t\t out of 10 \t\t\t out of 10 \n" +
"\t\t A1 \t A2 \t A3 \t A4");
for(int i = 0; i < assignments.length; i++)
{
output = output + "\n" + names[i];
for(int col = 0; col < assignments[i].length; col++)
{
output = output + "\t " + assignments[i][col] + "\t ";
}
output = output + "\t\t" + stuAvgArray[i];
output = output + "\n" + assignAvgArray[i];
}
return output;
}
}
i've bolded where java says the error is coming from. I am trying to read in, store, and then calculate for the array spots [[(0,0),(1,0),(2,0),(3,0),(4,0)],[(0,1),(1,1),(2,1),(3,1),(4,1)..etc]]
what Im trying to ask is how can I create a loop that doesn't give me this exception, storing all the values of each column into separate spots, and dividing each number stored in the new array by 5 to give me the average.
if there's anything else I can do to help you understand my problem please let me know.
PS: This is what It's supposed to look like;
Student Marks Average
Name out of 10 out of 10
A1 A2 A3 A4
Joe Smith 8 9 10 4 7.75
Tommy Jones 9 9 8 5 7.50
Sara Lee 0 10 10 9 7.25
Bob Fowler 10 9 9 0 7.00
Jane Doe 10 10 10 10 10.00
**Average 7.40 9.40 9.40 5.60**
I've calculated the row average but the bolded column average is giving me grief
The following line is wrong:
for(int row = 0; row < assignments[col].length; col++)
You are using row and increment col instead. As a result, you are doing an out of bound error in the block of that loop.
Replace it by:
for(int row = 0; row < assignments[col].length; row++)
But I'm afraid this is not the only problem. According to the way you read the input, assignments is a 2D-array with the row number for the first dimension and the column number for the second dimension. However, you are mixing the dimension here. As a reminder, you code is:
for (int col = 0; col < assignments.length; col++)
{
for (int row = 0; row < assignments[col].length; row++) {
assignAvgArray[row] += assignments[row][col];
}
assignAvgArray[col] = (assignAvgArray[col]/5);
}
As you can see, you are using col to identify the row. assignments.length is the number of lines.
for (int col = 0; col < assignments[0].length; col++)
{
for (int row = 0; row < assignments.length; row++) {
assignAvgArray[row] += assignments[row][col];
}
assignAvgArray[col] = (assignAvgArray[col]/5);
}
for (int col = 0; col < assignments.length; col++)
{
for(int row = 0; row < assignments[col].length; row++)
assignAvgArray[row] += assignments[row][col];
assignAvgArray[col] = (assignAvgArray[col]/5);
}
}
assignments.length is 5 so col can become 4.
assignAvgArray.length is 4. When you are giving the aassignAvgArray col=4 it will throw an arrayoutofboundException.
fix it ,and if you still have an error comment under my answer.

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

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.

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]});
}

Convert a 2d array to a organizing table look

I have convert a txt file into a 2d array, how can I make it look more organize?
My input file look like this:
[Name], Exam1, Exam2, Exam3
John, 99, 88, 89
May, 99, 100, 100
Mary, 100, 100, 100
Peter, 60, 60, 60
Currently I get:
[Name] Exam1 Exam2 Exam3
John 99 88 89
May 99 100 100
Mary 100 100 100
Peter 60 60 60
I want the data looks more like a table which is easier to read, how can I do that?
Code:
public static void main(String[] args) throws Exception{
File file = new File("test.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
int width = 0, height = 0;
String line = "";
/*Find number of row and column of the file.*/
while ((line = br.readLine()) != null)
{
if (width == 0)
{
/*Find the number of row using split method(",")*/
String[] str = line.split(",");
width = str.length;
}
height++;
}
System.out.println("Row : " + height);
System.out.println("Column : " + width);
/*Adding values to the 2D Array.*/
String[][] data = new String[height][width];
br = new BufferedReader(new FileReader(file));
for (int i = 0; i < height; i++)
{
if ((line = br.readLine()) != null)
{
for (int j = 0; j < width; j++)
{
String[] str = line.split(",");
data[i][j] = str[j];
System.out.print( data[i][j] + " ");
}
}
System.out.println("");
}
}
Thank you very much.
try output using printf
or you can use Formatter
I imagine your not going to want all that System.out stuff in your product but I am going to use it in an example, building on yours to show you the basic steps you will need to do.
Basically you need to make two passes over your data. First pass you should calculate the widest row of the data, so you can craft your ---- line. Then you add the like to whatever output type you are building (here it is System.out) and then walk the data again and add that to the output. You should add something like a newline or other terminator. If you want to line up the columns, you do the same thing but in the first step also record in another multi dimensional array the widest data in each column, and pad data that is shorter that the widest in each column when outputting (this will alter the width of your --- line so you will need to calculate this before building that line of course).
Here is your example modified a little bit with some of these ideas (not padding to line up the columns though, that is for you to do, it is easy trust me)
public static void main(String[] args) throws Exception {
/* Adding values to the 2D Array. */
String[][] data = { { "John", "99", "88", "89" },
{ "May", "99", "100", "100" } };
int wideRowWidth = 0;
int curRowWidth;
// WALK DATA ONCE TO FIND THE WIDEST ROW
for (int i = 0; i < data.length; i++) {
curRowWidth = 0;
for (int j = 0; j < data[i].length; j++) {
curRowWidth += data[i][j].length();
}
if (curRowWidth > wideRowWidth) {
wideRowWidth = curRowWidth;
}
}
// BUILD YOUR DASHED LINE
for (int i = 0; i < wideRowWidth + data[0].length -1; i++) {
System.out.print("-");
}
System.out.print("\n");
// USE YOUR DATA
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
System.out.print(data[i][j] + " ");
}
System.out.print("\n");
}
}
You can do it in this way, which is as follows :
// To Store and Show Values on the screen.
int columnWidth = 15;
for (int i = 0; i < height; i++)
{
if ((line = br.readLine()) != null)
{
// After reading, we are seperating them.
String[] str = line.split(", ");
for (int j = 0; j < width; j++)
{
data[i][j] = str[j];
// Here we are making the word length of each String equal,
// i.e. equal to column width. So that each String value comes
// below each other. Increase the value of columnWidth variable
// if you want to increase the width of a column or vice versa.
System.out.format("%-" + columnWidth + "s", data[i][j]);
}
}
System.out.print("\n");
}
Hope that might help.
Regards

Java: Print a 2D String array as a right-justified table

What is the best way to print the cells of a String[][] array as a right-justified table? For example, the input
{ { "x", "xxx" }, { "yyy", "y" }, { "zz", "zz" } }
should yield the output
x xxx
yyy y
zz zz
This seems like something that one should be able to accomplish using java.util.Formatter, but it doesn't seem to allow non-constant field widths. The best answer will use some standard method for padding the table cells, not the manual insertion of space characters.
Here's an answer, using dynamically-generated format strings for each column:
public static void printTable(String[][] table) {
// Find out what the maximum number of columns is in any row
int maxColumns = 0;
for (int i = 0; i < table.length; i++) {
maxColumns = Math.max(table[i].length, maxColumns);
}
// Find the maximum length of a string in each column
int[] lengths = new int[maxColumns];
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
lengths[j] = Math.max(table[i][j].length(), lengths[j]);
}
}
// Generate a format string for each column
String[] formats = new String[lengths.length];
for (int i = 0; i < lengths.length; i++) {
formats[i] = "%1$" + lengths[i] + "s"
+ (i + 1 == lengths.length ? "\n" : " ");
}
// Print 'em out
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.printf(formats[j], table[i][j]);
}
}
}
Indeed, if you specify a width for the fields, it should be right-justified.
If you need to have a dynamic padding, minimal for the longest string, you have to walk the array, getting the maximal width, generate the format string with the width computed from this maxima, and use it for format the output.
find the length of the longest string..
left pad all the strings with spaces until they r that length + 1
System.out.print them using 2 nested for loops

Categories