java - 如何使用具有通用数据类型的 printf/formatter 在 Java 和 POI 中的控制台中制作表格
问题描述
我对堆栈溢出相当陌生,我正试图在我的控制台中创建一个表格,但是当我尝试printf
用于填充或 javaFormatter
时,我似乎无法将它放入我的代码中,因为单元格可以是任何类型。
package com.codeblit.IO;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
public class ExcelReader {
private XSSFWorkbook workbook;
private XSSFSheet sheet;
private DataFormatter formatter;
private Cell cell;
private int rowCount, columnCount, rowHeight;
public ExcelReader(String filePath) {
init(filePath);
}
private void init(String filePath){
File src = new File(filePath);
//POI = Poor Obfuscation Implementation
//XSSF = use of xlsx format, from 2007 onwards
//HSSF = use of xls format, before 2007 and older
//All indexes start at 0 including: sheets, columns, rows etc.
try {
workbook = new XSSFWorkbook(src); //The full workbook created from file
} catch (IOException ioe){
System.err.println("[ERROR]; Workbook couldn't be created from file due to IO!");
ioe.printStackTrace();
} catch (InvalidFormatException ife){
System.err.println("[ERROR]: Workbook couldn't be created by file due to invalid formats!");
ife.printStackTrace();
}
formatter = new DataFormatter();
}
public String readAsString(int sheetIndex, int row, int column){
sheet = workbook.getSheetAt(sheetIndex); //The sheet at sheetIndex in the excel workbook
cell = sheet.getRow(row).getCell(column); //select the row and column, get the cell
return formatter.formatCellValue(cell); //return the value of the cell as a string even if it is numeric to avoid errors
}
public double readAsNumeric(int sheetIndex, int row, int column) {
sheet = workbook.getSheetAt(sheetIndex); //The sheet at sheetIndex in the excel workbook
return sheet.getRow(row).getCell(column).getNumericCellValue(); //select the row and column, and get the value as a double
}
public void printSheet(int sheetIndex){
sheet = workbook.getSheetAt(sheetIndex);
Iterator iterator = sheet.rowIterator(); //think of it as j for columns in multi dimensional arrays
Row row; //the current row
Cell cell;
while (iterator.hasNext()) { //detect if there is a next column, this works as
row = (Row) iterator.next();
System.out.print("\n");
for(int i = 0; i <= getRowCount(); i++){
cell = row.getCell(i); //the current cell in the row
System.out.print("\t\t\t");
switch (cell.getCellType()) {
case STRING:
System.out.print(cell.getStringCellValue());
break;
case NUMERIC:
if(DateUtil.isCellDateFormatted(cell))
System.out.println(cell.getDateCellValue());
System.out.print(cell.getNumericCellValue());
break;
case BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case FORMULA:
System.out.print(cell.getCellFormula());
break;
case ERROR:
System.out.print(cell.getErrorCellValue());
break;
default:
System.out.print("Unidentified Cell Value: " + cell.getCellType());
}
}
}
}
//********** GETTERS && SETTERS **********
public int getRowCount() {
//I set it here and not initialize so that every time we change the sheet and call this method again it will change the value instead of giving it the same one
rowCount = sheet.getLastRowNum();
return rowCount;
}
// 1. int noOfColumns = sh.getRow(0).getPhysicalNumberOfCells();
// 2. int noOfColumns = sh.getRow(0).getLastCellNum();
// There is a fine difference between them:
// Option 1 gives the no of columns which are actually filled with contents(If the 2nd column of 10 columns is not filled you will get 9) it will replace it with blank lines/spaces
// Option 2 just gives you the index of last column. Hence done 'getLastCellNum()'
public int getColumnCount(int rowIndex) {
//I set it here and not initialize so that every time we change the sheet and call this method again it will change the value instead of giving it the same one
columnCount = sheet.getRow(rowIndex).getLastCellNum();
return columnCount;
}
public int getRowHeight(Row row) {
rowHeight = row.getHeight();
return rowHeight;
}
}
重点在哪里:
while (iterator.hasNext()) { //detect if there is a next column, this works as
row = (Row) iterator.next();
System.out.print("\n");
for(int i = 0; i <= getRowCount(); i++){
cell = row.getCell(i); //the current cell in the row
System.out.print("\t\t\t");
switch (cell.getCellType()) {
case STRING:
System.out.print(cell.getStringCellValue());
break;
case NUMERIC:
if(DateUtil.isCellDateFormatted(cell))
System.out.println(cell.getDateCellValue());
System.out.print(cell.getNumericCellValue());
break;
case BOOLEAN:
System.out.print(cell.getBooleanCellValue());
break;
case FORMULA:
System.out.print(cell.getCellFormula());
break;
case ERROR:
System.out.print(cell.getErrorCellValue());
break;
default:
System.out.print("Unidentified Cell Value: " + cell.getCellType());
}
}
}
我希望它像第一列一样组织
谢谢。
解决方案
我解决了我需要创建一个方法的问题:
public void printSheetAsString(int sheetIndex){
sheet = workbook.getSheetAt(sheetIndex);
Row row;
//a row iterator which iterates through rows in a specified sheet
for(Iterator<Row> rowIterator = sheet.rowIterator(); rowIterator.hasNext();){
row = rowIterator.next(); //store the next element into the variable "row"
//a cell iterator which iterates through cells in the sheet's rows
for(Iterator<Cell> cellIterator = row.cellIterator(); cellIterator.hasNext();){
cell = cellIterator.next(); //store the next element into the variable "cell"
cell.setCellType(CellType.STRING); //set all the cells to type string so that we can print them out easily
//print "%" for place holder/variable, "-" for left justified table, "30" for spaces between each column, "s" for string
//this will print the cell then move to the next cell, print that cell, so on, till we reach the next row, which repeats the process, them move to next row, and so on till rowIterator.hasNext() returns false
System.out.printf("%-30s", cell.getStringCellValue());
}
System.out.println();
}
}
重点在哪里:
//print "%" for place holder/variable, "-" for left justified table, "30" for spaces between each column, "s" for string
//this will print the cell then move to the next cell, print that cell, so on, till we reach the next row, which repeats the process, them move to next row, and so on till rowIterator.hasNext() returns false
System.out.printf("%-30s", cell.getStringCellValue());
然后我制作了另一种方法来正确打印变量,而不是将它们转换为字符串并使用不推荐使用的方法:
public void printSheet(int sheetIndex){
sheet = workbook.getSheetAt(sheetIndex);
Row row;
for(Iterator<Row> rowIterator = sheet.rowIterator(); rowIterator.hasNext();){
row = rowIterator.next();
for(Iterator<Cell> cellIterator = row.cellIterator(); cellIterator.hasNext();){
cell = cellIterator.next();
switch (cell.getCellType()) {
case STRING:
System.out.printf("%-30s", cell.getStringCellValue());
break;
case NUMERIC:
if(DateUtil.isCellDateFormatted(cell))
System.out.printf("%-30s", cell.getDateCellValue().toString());
System.out.printf("%-30f", cell.getNumericCellValue());
break;
case BOOLEAN:
System.out.printf("%-30b", cell.getBooleanCellValue());
break;
case FORMULA:
System.out.printf("%-30s", cell.getCellFormula());
break;
case ERROR:
System.out.printf("%-30x", cell.getErrorCellValue());
break;
default:
System.err.print("[ERROR]: Unidentified Cell Value: " + cell.getCellType());
}
}
System.out.println();
}
}
}
这也给出了相同的结果。
谢谢!
推荐阅读
- javascript - 如何仅在对象内的所有 id 完成获取后才设置状态
- javascript - 需要帮助将多个音频文件静音
- python - 如何在 AzureStorageCheckpointLeaseManager 类中提供容器的完整路径
- c++ - 继承增加了类的大小
- mysql - 一旦连接限制达到,npm mysql 无法获取新连接
- .net - .Net Mvc 应用程序托管
- networking - UTP 电缆确实比用于串行通信的电缆更耐噪声吗?
- node.js - 如何在不重建整个图像的情况下编辑 docker 图像中的文件?
- winapi - 如何使用 GCC 操作 PE 特性
- model-view-controller - 解决方案探索中的区域选项未显示在 Visual Studio 2019 中