Apache POI: API для идентификации таблиц на листе excel и их чтения
Существует ли метод, который возвращает список таблиц, присутствующих на листе? Мое требование состоит в том, чтобы получить данные из нескольких таблиц, присутствующих на листе.
3 ответа:
Предположим, что вы используете API
XSSF
для файлов excel.xlsx
. Если таблицы были созданы с помощьюInsert->Table
, то вы можете прочитать их, используя следующее :XSSFWorkbook workbook = new XSSFWorkbook(new File("test.xlsx")); int numberOfSheets = workbook.getNumberOfSheets(); for(int sheetIdx = 0; sheetIdx < numberOfSheets; sheetIdx++) { XSSFSheet sheet = workbook.getSheetAt(sheetIdx); List<XSSFTable> tables = sheet.getTables(); for(XSSFTable t : tables) { System.out.println(t.getDisplayName()); System.out.println(t.getName()); System.out.println(t.getNumerOfMappedColumns()); } }
Если под
table
вы подразумеваете все, что имеет границу, то вам нужно создать нетривиальный алгоритм, который считывает все ячейки каждого листа и проверяет границы (например,leftBorderColor
,rightBorderColor
,topBorderColor
,bottomBorderColor
) и, определив, что такоеtable
, Проверьте, нашли ли вы его.
Для всех тех, кто хочет читать таблицы из кода java, вот рабочий код.
XSSFWorkbook workbook = new XSSFWorkbook(new File("test.xlsx")); int numberOfSheets = workbook.getNumberOfSheets(); for (int sheetIdx = 0; sheetIdx < numberOfSheets; sheetIdx++) { XSSFSheet sheet = workbook.getSheetAt(sheetIdx); List<XSSFTable> tables = sheet.getTables(); for (XSSFTable t : tables) { System.out.println(t.getDisplayName()); System.out.println(t.getName()); System.out.println(t.getNumerOfMappedColumns()); int startRow = t.getStartCellReference().getRow(); int endRow = t.getEndCellReference().getRow(); System.out.println("startRow = " + startRow); System.out.println("endRow = " + endRow); int startColumn = t.getStartCellReference().getCol(); int endColumn = t.getEndCellReference().getCol(); System.out.println("startColumn = " + startColumn); System.out.println("endColumn = " + endColumn); for (int i = startRow; i <= endRow; i++) { String cellVal = ""; for (int j = startColumn; j <= endColumn; j++) { XSSFCell cell = sheet.getRow(i).getCell(j); if (cell != null) { cellVal = cell.getStringCellValue(); } System.out.print(cellVal + "\t"); } System.out.println(); } } } workbook.close();
Я написал это, чтобы использовать его с классом Pojo и аннотациями:
import java.io.File; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFTable; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.madx.finance.data.utils.exels.read.ExelColumn; public class Main { public static void main(String[] args) throws Exception { readExel(ExamplePojo.class); } public static class ExamplePojo { public ExamplePojo(){} @ExelColumn(columnName="Column 1 String Name On Exel") protected String column1; @ExelColumn(columnName="Column 2 String Name On Exel") protected String column2; } public static <T> List<T> readExel(Class<T> clazz) throws Exception { List<T> rows = new ArrayList<T>(); XSSFWorkbook workbook = new XSSFWorkbook(new File("test.xlsx")); int numberOfSheets = workbook.getNumberOfSheets(); for (int sheetIdx = 0; sheetIdx < numberOfSheets; sheetIdx++) { XSSFSheet sheet = workbook.getSheetAt(sheetIdx); List<XSSFTable> tables = sheet.getTables(); for (XSSFTable t : tables) { System.out.println(t.getDisplayName()); System.out.println(t.getName()); System.out.println(t.getNumerOfMappedColumns()); int startRow = t.getStartCellReference().getRow(); int endRow = t.getEndCellReference().getRow(); System.out.println("startRow = " + startRow); System.out.println("endRow = " + endRow); int startColumn = t.getStartCellReference().getCol(); int endColumn = t.getEndCellReference().getCol(); System.out.println("startColumn = " + startColumn); System.out.println("endColumn = " + endColumn); // Loads all the annotated fields and builds a map for: // columnName, field List<Field> annotatedFields = FieldUtils.getFieldsListWithAnnotation(clazz, ExelColumn.class); Map<String, Field> annotatedFieldsMap = new HashMap<String, Field>(); for (Field field : annotatedFields) annotatedFieldsMap.put(field.getAnnotation(ExelColumn.class).columnName(), field); // Reads the used header names List<Pair<Integer, Field>> consideredColumns = new ArrayList<Pair<Integer, Field>>(); for (int j = startColumn; j <= endColumn; j++) { XSSFCell cell = sheet.getRow(startRow).getCell(j); if (cell != null) { String columnName = cell.getStringCellValue(); Field field = annotatedFieldsMap.get(columnName); if (field != null) { Integer cellColumn = j; Pair<Integer, Field> p = new ImmutablePair<Integer, Field>(cellColumn, field); consideredColumns.add(p); } } } for (int i = startRow + 1; i <= endRow; i++) { try { T row = clazz.newInstance(); for (Pair<Integer, Field> pair : consideredColumns) { XSSFCell cell = sheet.getRow(i).getCell(pair.getKey()); if (cell != null) { Field field = pair.getValue(); field.setAccessible(true); Class<?> fieldClass = field.getType(); if(Number.class.isAssignableFrom(fieldClass)){ field.set(row, cell.getNumericCellValue()); } else { field.set(row, cell.getStringCellValue()); } } } rows.add(row); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } } } workbook.close(); return rows; } }