650 lines
20 KiB
Java
650 lines
20 KiB
Java
package de.hs_mannheim.informatik.spreadsheet;
|
|
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Scanner;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* A simplified spreadsheet class for the PR1 programming lab at Hochschule Mannheim.
|
|
* One aspect worth mentioning is that it only supports long numbers, not doubles.
|
|
*
|
|
* @author Oliver Hummel
|
|
*/
|
|
public class Spreadsheet {
|
|
Cell[][] cells;
|
|
|
|
/**
|
|
* Constructor that creates a Spreadsheet of size rows * cols.
|
|
*
|
|
* @param rows number of rows
|
|
* @param cols number of columns
|
|
*/
|
|
public Spreadsheet(int rows, int cols) {
|
|
|
|
if(rows>99)
|
|
rows = 99;
|
|
else if(rows<1)
|
|
rows = 1;
|
|
if(cols < 1)
|
|
cols = 1;
|
|
else if(cols > 26)
|
|
cols = 26;
|
|
|
|
cells = new Cell[rows][cols];
|
|
|
|
for (int r = 0; r < rows; r++)
|
|
for (int c = 0; c < cols; c++)
|
|
cells[r][c] = new Cell();
|
|
}
|
|
|
|
// -----
|
|
// retrieve or change values of cells
|
|
|
|
private String get(int row, int col) {
|
|
return cells[row][col].getValue();
|
|
}
|
|
|
|
public String get(String cellName) {
|
|
cellName = cellName.toUpperCase();
|
|
return get(getRow(cellName)-1, getCol(cellName)-1);
|
|
}
|
|
|
|
public String getCellName(int row, int col) {
|
|
return ("" + ((char) ('A' + col))) + (row+1);
|
|
}
|
|
|
|
private void put(int row, int col, String value) {
|
|
if (!value.startsWith("="))
|
|
cells[row][col].setValue(value);
|
|
else {
|
|
cells[row][col].setFormula(value);
|
|
evaluateCell(row, col);
|
|
}
|
|
}
|
|
|
|
public void put(String cellName, String value) {
|
|
cellName = cellName.toUpperCase();
|
|
put(getRow(cellName)-1, getCol(cellName)-1, value);
|
|
}
|
|
|
|
private int getCol(String cellName) {
|
|
return cellName.charAt(0) - 'A' + 1;
|
|
}
|
|
|
|
private int getRow(String cellName) {
|
|
if(cellName.length()>2)
|
|
return Integer.parseInt(""+cellName.charAt(1) + cellName.charAt(2));
|
|
return cellName.charAt(1) - '1' + 1;
|
|
}
|
|
|
|
// -----
|
|
// business logic
|
|
|
|
/**
|
|
* A method for reading in data from a CSV file.
|
|
*
|
|
* @param path The file to read.
|
|
* @param separator The char used to split up the input, e.g. a comma or a semicolon.
|
|
* @param startCellName The upper left cell where data from the CSV file should be inserted.
|
|
* @return Nothing.
|
|
* @throws IOException If path does not exist.
|
|
*/
|
|
public void readCsv(String path, char separator, String startCellName) throws FileNotFoundException {
|
|
Scanner sc = new Scanner(new File(path));
|
|
ArrayList<String> memList = new ArrayList<>();
|
|
|
|
while (sc.hasNextLine()) {
|
|
memList.add(sc.nextLine());
|
|
}
|
|
|
|
String[][] memArr = new String[memList.size()][];
|
|
for(int i = 0; i < memList.size(); i++)
|
|
memArr[i] = (memList.get(i)).split(String.valueOf(separator));
|
|
|
|
for (int r = getRow(startCellName)-1; r < memList.size(); r++)
|
|
for (int c = getCol(startCellName)-1; c < memList.get(0).length(); c++)
|
|
if(c<memArr[r].length)
|
|
cells[r][c].setFormula(memArr[r][c]);
|
|
|
|
sc.close();
|
|
}
|
|
|
|
/**
|
|
* A method for saving data to a CSV file.
|
|
*
|
|
* @param path The file to write.
|
|
* @return Nothing.
|
|
* @throws IOException If path does not exist.
|
|
*/
|
|
public void saveCsv(String path) throws FileNotFoundException {
|
|
PrintWriter out = new PrintWriter(path);
|
|
|
|
for (Cell[] row : cells) {
|
|
for (Cell cell : row) {
|
|
if (!cell.getFormula().isEmpty())
|
|
out.print("=" + cell.getFormula());
|
|
else
|
|
out.print(cell.getValue());
|
|
|
|
if (cell != row[cells[0].length - 1])
|
|
out.print(",");
|
|
}
|
|
out.println();
|
|
}
|
|
|
|
out.close();
|
|
}
|
|
|
|
/**
|
|
* This method does the actual evaluation/calcluation of a specific cell
|
|
*
|
|
* @param row,col the name of row and column of the cell
|
|
* @return Nothing.
|
|
*/
|
|
private void evaluateCell(int row, int col) {
|
|
String formula = cells[row][col].getFormula();
|
|
double result = 0;
|
|
String substringStartCell1 = "";
|
|
String substringStartCell2 = "";
|
|
String substringStartCell3 = "";
|
|
String substringEndCell1 = "";
|
|
String substringEndCell2 = "";
|
|
|
|
if(formula.length()>9) {
|
|
substringStartCell1 = formula.substring(formula.length() - 6, formula.length() - 4);
|
|
substringStartCell2 = formula.substring(formula.length() - 7, formula.length() - 5);
|
|
substringStartCell3 = formula.substring(formula.length() - 8, formula.length() - 5);
|
|
substringEndCell1 = formula.substring(formula.length() - 3, formula.length() - 1);
|
|
substringEndCell2 = formula.substring(formula.length() - 4, formula.length() - 1);
|
|
}
|
|
|
|
if (formula.startsWith("SUMME("))// e.g. SUMME(A3:A8)
|
|
if (formula.length() < 13)
|
|
result = sum(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 14)
|
|
result = sum(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 15)
|
|
result = sum(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (formula.startsWith("PRODUKT(")) // e.g. PRODUKT(A3:B9)
|
|
if (formula.length() < 15)
|
|
result = product(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 16 && !substringEndCell2.contains(":"))
|
|
result = product(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 17)
|
|
result = product(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (formula.startsWith("MITTELWERT(")) // e.g. MITTELWERT(A3:A5)
|
|
if (formula.length() < 18)
|
|
result = average(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 19)
|
|
result = average(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 20)
|
|
result = average(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (formula.startsWith("STABW(")) // e.g. STABW(C6:D8) -> Standardabweichung
|
|
if (formula.length() < 13)
|
|
result = standardDeviation(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 14)
|
|
result = standardDeviation(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 15)
|
|
result = standardDeviation(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (formula.startsWith("MIN(")) // e.g. MIN(C1:H13) -> kleinster Wert
|
|
if (formula.length() < 11)
|
|
result = min(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 12)
|
|
result = min(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 13)
|
|
result = min(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (formula.startsWith("MAX(")) // e.g. MAX(A1:A10) -> größter Wert
|
|
if (formula.length() < 11)
|
|
result = max(substringStartCell1, substringEndCell1);
|
|
else if (formula.length() < 12)
|
|
result = max(substringStartCell2, substringEndCell2);
|
|
else if (formula.length() < 13)
|
|
result = max(substringStartCell3, substringEndCell2);
|
|
else
|
|
result = 0;
|
|
|
|
|
|
else if (!formula.isEmpty()) {
|
|
try {
|
|
result = calculate(formula);
|
|
} catch (ArithmeticException ae) {
|
|
result = 0;
|
|
}
|
|
}
|
|
|
|
if(!cells[row][col].getFormula().isEmpty())
|
|
if(String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(0)=='0'&&
|
|
String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(1)=='0')
|
|
cells[row][col].setValue(String.format("%.0f",result));
|
|
|
|
else if(String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(1)=='0')
|
|
cells[row][col].setValue(String.format("%.1f",result));
|
|
|
|
else
|
|
cells[row][col].setValue(String.format("%.2f",result));
|
|
}
|
|
|
|
/**
|
|
* Method for calculating the sum of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The sum calculated.
|
|
*/
|
|
private double sum(String startCellName, String endCellName) {
|
|
double result = 0;
|
|
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty())
|
|
result += Double.parseDouble(cells[r][c].getValue());
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Method for calculating the product of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The product calculated.
|
|
*/
|
|
private double product(String startCellName, String endCellName) {
|
|
double result = 0;
|
|
int counter = 0;
|
|
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty())
|
|
if(counter>0)
|
|
result *= Double.parseDouble(cells[r][c].getValue());
|
|
else {
|
|
result = Double.parseDouble(cells[r][c].getValue());
|
|
counter++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Method for calculating the average of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The average calculated.
|
|
*/
|
|
private double average(String startCellName, String endCellName) {
|
|
double result = 0;
|
|
int counter = 0;
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty()) {
|
|
result += Double.parseDouble(cells[r][c].getValue());
|
|
counter++;
|
|
}
|
|
if(result!=0)
|
|
result /= counter;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Method for calculating the standardDeviation of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The standardDeviation calculated.
|
|
*/
|
|
private double standardDeviation(String startCellName, String endCellName){
|
|
ArrayList<String> cellNames = new ArrayList<>();
|
|
|
|
double avg = 0;
|
|
int counter = 0;
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty()){
|
|
avg += Double.parseDouble(cells[r][c].getValue());
|
|
counter++;
|
|
cellNames.add(getCellName(r, c));
|
|
}
|
|
avg /= counter;
|
|
//average/ add cell names to list
|
|
|
|
if(cellNames.isEmpty())
|
|
return 0;
|
|
|
|
ArrayList<String> copyCellNames = new ArrayList<>(cellNames);
|
|
double[] frequency = new double[cellNames.size()];
|
|
Arrays.fill(frequency,1);
|
|
ArrayList<Double> relativeFrequency = new ArrayList<>();
|
|
double mem = 0;
|
|
|
|
for(int i = 0; i< cellNames.size(); i++) {
|
|
for(int t = 0; t<cellNames.size(); t++){
|
|
if((t!=i)&&(!get(cellNames.get(i)).isEmpty())&&(get(cellNames.get(i)).equals(get(cellNames.get(t))))){
|
|
cellNames.remove(t);
|
|
frequency[i] ++;
|
|
t = 0;
|
|
}
|
|
}
|
|
}
|
|
//delete all duplicates
|
|
|
|
for(int i = 0; i< cellNames.size(); i++)
|
|
relativeFrequency.add(i,frequency[i]/copyCellNames.size());
|
|
|
|
if(get(cellNames.get(0)).isEmpty())
|
|
mem = ((0 - avg)*(0 - avg))
|
|
* relativeFrequency.get(0);
|
|
|
|
else
|
|
mem = ((Double.parseDouble(get(cellNames.get(0))) - avg)*(Double.parseDouble(get(cellNames.get(0))) - avg))
|
|
* relativeFrequency.get(0);
|
|
|
|
for(int i = 1; i<cellNames.size(); i++)
|
|
if(get(cellNames.get(i)).isEmpty())
|
|
mem += ((0 - avg)*(0 - avg))
|
|
* relativeFrequency.get(i);
|
|
else
|
|
mem += ((Double.parseDouble(get(cellNames.get(i))) - avg)*(Double.parseDouble(get(cellNames.get(i))) - avg))
|
|
* relativeFrequency.get(i);
|
|
return Math.sqrt(mem);
|
|
//standardDeviation formula
|
|
}
|
|
|
|
/**
|
|
* Method to find out the lowest number of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The lowest number.
|
|
*/
|
|
private double min(String startCellName, String endCellName){
|
|
ArrayList<String> cellNames = new ArrayList<>();
|
|
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty())
|
|
cellNames.add(getCellName(r, c));
|
|
|
|
if(cellNames.isEmpty())
|
|
return 0;
|
|
|
|
double result = Double.parseDouble(get(cellNames.get(0)));
|
|
for(int i = 0; i< cellNames.size(); i++)
|
|
try {
|
|
if (result > Double.parseDouble(get(cellNames.get(i))))
|
|
result = Double.parseDouble(get(cellNames.get(i)));
|
|
} catch(NumberFormatException n){}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Method to find out the highest number of a rectangular block of cells, such as from A1 to B3.
|
|
*
|
|
* @param startCellName The name of the cell in the upper left corner of the rectangle.
|
|
* @param endCellName The name of the cell in the lower right corner of the rectangle.
|
|
* @return The highest number.
|
|
*/
|
|
private double max(String startCellName, String endCellName){
|
|
ArrayList<String> cellNames = new ArrayList<>();
|
|
|
|
for(int r = getRow(startCellName)-1; r<getRow(endCellName); r++)
|
|
for(int c = getCol(startCellName)-1; c<getCol(endCellName); c++)
|
|
if(!cells[r][c].isEmpty())
|
|
cellNames.add(getCellName(r, c));
|
|
|
|
if(cellNames.isEmpty())
|
|
return 0;
|
|
|
|
double result = Double.parseDouble(get(cellNames.get(0)));
|
|
for(int i = 0; i< cellNames.size(); i++)
|
|
try {
|
|
if (result < Double.parseDouble(get(cellNames.get(i))))
|
|
result = Double.parseDouble(get(cellNames.get(i)));
|
|
} catch(NumberFormatException n){}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method calculates the result of a "normal" algebraic expression. It only needs to support
|
|
* expressions like =B4 or =2+A3-B2, i.e. only with int numbers and other cells and with plus,
|
|
* minus, times, split only. An expression always starts with either a number or a cell name. If it
|
|
* continues, it is guaranteed that this is followed by an operator and either a number or a
|
|
* cell name again. It is NOT required to implement dot before dash or parentheses in formulas.
|
|
*
|
|
* @param formula The expression to be evaluated.
|
|
* @return The result calculated.
|
|
*/
|
|
private double calculate(String formula) throws ArithmeticException {
|
|
Matcher m = Pattern.compile("([A-Z][1-9][0-9]*)|[-+*/]|[0-9]+").matcher(formula);
|
|
|
|
double result = 0;
|
|
double currentOperand = 0;
|
|
String currentOperator = "+";
|
|
boolean firstOperator = true;
|
|
|
|
while (m.find()) {
|
|
String s = m.group();
|
|
|
|
if (s.matches(("[0-9]+")))
|
|
currentOperand = Double.parseDouble(s);
|
|
else if (s.matches("[A-Z][1-9][0-9]*") && get(s).isEmpty())
|
|
currentOperand = 0;
|
|
else if (s.matches("[A-Z][1-9][0-9]*")) {
|
|
currentOperand = Double.parseDouble(get(s));
|
|
} else {
|
|
if (!firstOperator) {
|
|
result = evaluateOperator(result, currentOperand, currentOperator);
|
|
} else {
|
|
result = currentOperand;
|
|
firstOperator = false;
|
|
}
|
|
currentOperator = s;
|
|
}
|
|
}
|
|
|
|
if (!firstOperator) {
|
|
result = evaluateOperator(result, currentOperand, currentOperator);
|
|
} else
|
|
result = currentOperand;
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method does the actual calculation with the current operator,
|
|
* the left and right operands provided by the calculate method.
|
|
*
|
|
* @param leftOperand The first operand used to calculate.
|
|
* @param rightOperand The second operand used to calculate.
|
|
* @param currentOperator The current operator used to calculate.
|
|
* @return The partial result calculated.
|
|
*/
|
|
private double evaluateOperator(double leftOperand, double rightOperand, String currentOperator) {
|
|
switch (currentOperator) {
|
|
case "+":
|
|
return (leftOperand + rightOperand);
|
|
case "-":
|
|
return (leftOperand - rightOperand);
|
|
case "*":
|
|
return (leftOperand * rightOperand);
|
|
case "/":
|
|
return (leftOperand / rightOperand);
|
|
default:
|
|
throw new IllegalArgumentException("Invalid operator: " + currentOperator);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This method updates all cells value by provided formula.
|
|
*
|
|
* @return nothing.
|
|
*/
|
|
public void updateSpreadsheet() {
|
|
for (int r = 0; r < cells.length; r++)
|
|
for (int c = 0; c < cells[r].length; c++)
|
|
evaluateCell(r, c);
|
|
}
|
|
|
|
|
|
///--- ui methods
|
|
|
|
/**
|
|
* This method scans and evaluates the user input.
|
|
*
|
|
* @return The boolean true, when the programm is finished by the user input.
|
|
*/
|
|
public boolean cellInput() throws FileNotFoundException {
|
|
Scanner cs = new Scanner(System.in);
|
|
|
|
String input = cs.nextLine();
|
|
ArrayList<String> inputs = new ArrayList<>();
|
|
for(int i =0; i<input.split(" ").length; i++)
|
|
inputs.add(input.split(" ")[i]);
|
|
|
|
|
|
if (inputs.contains("STOP")) {
|
|
System.out.println("\nDas Programm wurde beendet.");
|
|
return true;
|
|
} else if (inputs.contains("HILFE")) {
|
|
Axel.help();
|
|
System.out.println("\nEnter zum fortfahren.");
|
|
cs.nextLine();
|
|
}else if (inputs.contains("EINLESEN")){
|
|
readCsv(inputs.get(1), inputs.get(2).charAt(0), inputs.get(3));
|
|
System.out.println("\nEinlesen erfolgreich.");
|
|
System.out.println("\nEnter zum fortfahren.");
|
|
cs.nextLine();
|
|
}else if (inputs.contains("SPEICHERN")) {
|
|
saveCsv(inputs.get(1));
|
|
System.out.println("\nSpeichern erfolgreich.");
|
|
System.out.println("\nEnter zum fortfahren.");
|
|
cs.nextLine();
|
|
}else if (inputs.contains("FORMELN")) {
|
|
System.out.println(toStringShowFormula());
|
|
System.out.println("\nEnter zum fortfahren.");
|
|
cs.nextLine();
|
|
}else {
|
|
cells[getRow(inputs.get(0))-1][getCol(inputs.get(0))-1].setFormula(inputs.get(1));
|
|
System.out.println("\nEnter zum fortfahren.");
|
|
cs.nextLine();
|
|
}
|
|
|
|
updateSpreadsheet();
|
|
|
|
inputs.clear();
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* This method outputs the cell spreadsheet with all the values.
|
|
*
|
|
* @return nothing.
|
|
*/
|
|
public String toString() {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append(System.lineSeparator());
|
|
sb.append(System.lineSeparator());
|
|
sb.append(" |");
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append(" " + (char) ('A' + i) + " |");
|
|
}
|
|
int rc = 1;
|
|
for (int r = 0; r < cells.length; r++) {
|
|
sb.append(System.lineSeparator());
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append("----------------------");
|
|
}
|
|
sb.append("------");
|
|
sb.append(System.lineSeparator());
|
|
sb.append(String.format(" " + "%2s", rc++) + " |");
|
|
|
|
for (int c = 0; c < cells[r].length; c++) {
|
|
if((cells[r][c].getValue()).length()>19)
|
|
sb.append(" " + String.format("%19s", cells[r][c].getValue()).substring(0,19) + " |");
|
|
else
|
|
sb.append(" " + String.format("%19s", cells[r][c].getValue()) + " |");
|
|
}
|
|
|
|
}
|
|
sb.append(System.lineSeparator());
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append("----------------------");
|
|
}
|
|
sb.append("------");
|
|
sb.append(System.lineSeparator());
|
|
return sb.toString();
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* This method outputs the cell spreadsheet with all the formulas instead of the values.
|
|
*
|
|
* @return nothing.
|
|
*/
|
|
public String toStringShowFormula() {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.append(System.lineSeparator());
|
|
sb.append(System.lineSeparator());
|
|
sb.append(" |");
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append(" " + (char) ('A' + i) + " |");
|
|
}
|
|
int rc = 1;
|
|
for (int r = 0; r < cells.length; r++) {
|
|
sb.append(System.lineSeparator());
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append("----------------------");
|
|
}
|
|
sb.append("------");
|
|
sb.append(System.lineSeparator());
|
|
sb.append(String.format(" " + "%2s", rc++) + " |");
|
|
|
|
for (int c = 0; c < cells[r].length; c++) {
|
|
sb.append(" " + String.format("%19s", cells[r][c].getFormula()) + " |");
|
|
}
|
|
|
|
}
|
|
sb.append(System.lineSeparator());
|
|
for (int i = 0; i < cells[0].length; i++) {
|
|
sb.append("----------------------");
|
|
}
|
|
sb.append("------");
|
|
sb.append(System.lineSeparator());
|
|
return sb.toString();
|
|
|
|
|
|
}
|
|
}
|