简体   繁体   English

Apache POI:用于识别Excel工作表中的表并读取它们的API

[英]Apache POI : API to identify tables in the excel sheet and read them

Is there any method which returns a list of tables present in the sheet? 是否有任何方法可以返回工作表中存在的表列表? My requirement is to fetch data from multiple tables present on the sheet. 我的要求是从工作表上的多个表中获取数据。

Let's assume that you are using the XSSF API for .xlsx excel files. 假设您正在使用XSSF API来处理.xlsx excel文件。 If the tables were created by Insert->Table then you can read them by using this : 如果表是由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());
    }
}

If by table you mean anything that has a border then you have to create a non-trivial algorithm that reads all the cells of every sheet and checks the boundaries (eg leftBorderColor , rightBorderColor , topBorderColor , bottomBorderColor ) and by defining what consists a table check if you've found it. 如果你用table表示任何有边框的东西,那么你必须创建一个非平凡的算法来读取每个工作表的所有单元格并检查边界(例如leftBorderColorrightBorderColortopBorderColorbottomBorderColor )以及通过定义table检查的内容如果你找到了

For all those who want to read tables from a java code, here is the working code. 对于所有想要从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();

I wrote this to use it with a Pojo class and annotations: 我写这个用它与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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM