Получение конкретных данных из листа Excel JAVA

Я пытаюсь получить конкретные данные из листа Excel, данные динамические. Это может быть что угодно на самом деле. Заголовки столбцов — это единственное, что я могу использовать для заполнителей, но позиции заголовков столбцов могут различаться на листе.

Например, у меня есть такой лист:

|Имя| Фамилия| Значение|

|бар | какашки | 5|

|баз | фу | 7|

Но, например, мне нужно пройти лист, чтобы получить столбец фамилии, а затем, если я найду фамилию = 'poo', я должен затем вытащить соответствующее значение, которое на листе находится в следующем столбце, но это динамично. Столбец фамилия и значение не всегда рядом друг с другом, они могут быть в любом месте вверху. Но если я нахожу конкретную «вещь» в столбце фамилии, мне нужно получить ее значение.

Мне удалось пройти через лист и сохранить все данные в массиве 2d и отобразить эти данные. судя по проведенным исследованиям, это неэффективный подход, поскольку перемещение и хранение больших данных из листов может использовать много памяти. Я читал, что вы можете читать лист Excel и вместо того, чтобы сохранять эти значения в массиве, вы можете сразу же записать их на другой лист, если они соответствуют определенному условию. Например: (псевдо) If(columnheader == surname && surname == foo), затем получите соответствующее значение, затем запишите это значение на новый лист.

Итак, мои вопросы:

1. Как мне выполнить итерацию по листу, не сохраняя его в массиве, и записывая его прямо на другой лист, если он соответствует условию?

2. Из кода, который у меня есть ниже, как мне добиться сортировки данных в массиве и найти, если фамилия = foo получает соответствующее значение?

Как я уже сказал, данные на листе являются динамическими, за исключением заголовков столбцов, но их позиции в качестве заголовков являются динамическими.

Извините за длинное сообщение, любая помощь будет принята с благодарностью.

package demo.poi;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class test  {

    public static void main(String[] args) throws Exception {

        File excel = new File("test.xlsx");
        FileInputStream fis = new FileInputStream(excel);

        XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFSheet ws = wb.getSheetAt(0);
        ws.setForceFormulaRecalculation(true);

        int rowNum = ws.getLastRowNum() + 1;
        int colNum = ws.getRow(0).getLastCellNum();
        int surnameHeaderIndex = -1, valueHeaderIndex = -1;

        //Read the headers first. Locate the ones you need
        XSSFRow rowHeader = ws.getRow(0);
        for (int j = 0; j < colNum; j++) {
            XSSFCell cell = rowHeader.getCell(j);
            String cellValue = cellToString(cell);
            if("SURNAME".equalsIgnoreCase(cellValue)) {
                surnameHeaderIndex = j;
            } else if("VALUE".equalsIgnoreCase(cellValue)) {
                valueHeaderIndex = j;
            }
        }

        if(surnameHeaderIndex == -1 || valueHeaderIndex == -1) {
            throw new Exception("Could not find header indexes\nSurname : " + surnameHeaderIndex + " | Value : " + valueHeaderIndex);
        }
        //createnew workbook
        XSSFWorkbook workbook = new XSSFWorkbook(); 		
		//Create a blank sheet
		XSSFSheet sheet = workbook.createSheet("data");
		
        for (int i = 1; i < rowNum; i++) {
            XSSFRow row = ws.getRow(i);
           row = sheet.createRow(rowNum++);
            String surname = cellToString(row.getCell(surnameHeaderIndex));
            String value = cellToString(row.getCell(valueHeaderIndex));
            int cellIndex = 0;
            row.createCell(cellIndex++).setCellValue(surname);
            row.createCell(cellIndex++).setCellValue(value);
            

            
        }
        FileOutputStream fos = new FileOutputStream(new File("test1.xlsx"));
        workbook.write(fos);
        fos.close();
    }

    public static String cellToString(XSSFCell cell) {

        int type;
        Object result = null;
        type = cell.getCellType();

        switch (type) {

        case XSSFCell.CELL_TYPE_NUMERIC:
            result = BigDecimal.valueOf(cell.getNumericCellValue())
                    .toPlainString();

            break;
        case XSSFCell.CELL_TYPE_STRING:
            result = cell.getStringCellValue();
            break;
        case XSSFCell.CELL_TYPE_BLANK:
            result = "";
            break;
        case XSSFCell.CELL_TYPE_FORMULA:
            result = cell.getCellFormula();
        }

        return result.toString();
    }
}


person JavaPotter    schedule 15.03.2015    source источник
comment
Приведите полный пример и желаемый результат. Вы упомянули сортировку, но я не совсем понимаю, что вы имеете в виду.   -  person Alkis Kalogeris    schedule 15.03.2015
comment
привет, Итак, в основном из этого листа Excel. Я хочу повторить и найти конкретные значения. Например, теперь, когда у меня есть все данные в массиве, мне нужно что-то с ним делать. Например: результат, который я ищу, - это когда я нахожу столбец «Фамилия», нахожу значение foo, и когда вы найдете foo, перейдите в столбец значений и получить соответствующий номер. Если вы посмотрите на демонстрационный лист, значение для foo равно 7. Но как мне получить местоположение foo и связать его со значением 7, если позиции заголовков столбцов являются динамическими?   -  person JavaPotter    schedule 15.03.2015


Ответы (1)


Что-то вроде этого должно быть хорошей отправной точкой. В основном вы анализируете первую строку, где расположены заголовки. Вы находите нужные позиции заголовков и сохраняете их. В этом примере необходимы только два заголовка (фамилия, значение), поэтому я просто сохраняю две переменные. Если их больше, то решением будет сохранить положение этих заголовков в HashMap, где ключ — это имя заголовка. После этого начинается итерация строк. Программа анализирует значения необходимых столбцов (row.getCell(index)). Теперь у вас есть те значения, которые вам нужны, и только они. Вы можете делать все, что хотите, вы можете распечатать их или записать файл или еще что-то.

Вот пример. Обработка ошибок зависит от вас. Это только пример.

package POIParser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class MainPoi {

    public static void main(String[] args) throws Exception {

        File excel = new File("test.xlsx");
        FileInputStream fis = new FileInputStream(excel);

        XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFSheet ws = wb.getSheetAt(0);
        ws.setForceFormulaRecalculation(true);

        int rowNum = ws.getLastRowNum() + 1;
        int colNum = ws.getRow(0).getLastCellNum();
        int surnameHeaderIndex = -1, valueHeaderIndex = -1;

        // Read the headers first. Locate the ones you need
        XSSFRow rowHeader = ws.getRow(0);
        for (int j = 0; j < colNum; j++) {
            XSSFCell cell = rowHeader.getCell(j);
            String cellValue = cellToString(cell);
            if ("SURNAME".equalsIgnoreCase(cellValue)) {
                surnameHeaderIndex = j;
            } else if ("VALUE".equalsIgnoreCase(cellValue)) {
                valueHeaderIndex = j;
            }
        }

        if (surnameHeaderIndex == -1 || valueHeaderIndex == -1) {
            throw new Exception("Could not find header indexes\nSurname : "
                    + surnameHeaderIndex + " | Value : " + valueHeaderIndex);
        }
        // createnew workbook
        XSSFWorkbook workbook = new XSSFWorkbook();
        // Create a blank sheet
        XSSFSheet sheet = workbook.createSheet("data");

        for (int i = 1; i < rowNum; i++) {
            XSSFRow row = ws.getRow(i);
            String surname = cellToString(row.getCell(surnameHeaderIndex));
            String value = cellToString(row.getCell(valueHeaderIndex));
            int cellIndex = 0;
            //Create a newRow object for the output excel. 
            //We begin for i = 1, because of the headers from the input excel, so we go minus 1 in the new (no headers).
            //If for the output we need headers, add them outside this for loop, and go with i, not i-1
            XSSFRow newRow = sheet.createRow(i-1);  
            newRow.createCell(cellIndex++).setCellValue(surname);
            newRow.createCell(cellIndex++).setCellValue(value);
        }

        FileOutputStream fos = new FileOutputStream(new File("test1.xlsx"));
        workbook.write(fos);
        fos.close();
    }

    public static String cellToString(XSSFCell cell) {

        int type;
        Object result = null;
        type = cell.getCellType();

        switch (type) {

        case XSSFCell.CELL_TYPE_NUMERIC:
            result = BigDecimal.valueOf(cell.getNumericCellValue())
                    .toPlainString();

            break;
        case XSSFCell.CELL_TYPE_STRING:
            result = cell.getStringCellValue();
            break;
        case XSSFCell.CELL_TYPE_BLANK:
            result = "";
            break;
        case XSSFCell.CELL_TYPE_FORMULA:
            result = cell.getCellFormula();
        }

        return result.toString();
    }
}
person Alkis Kalogeris    schedule 15.03.2015
comment
спасибо, alkis, это определенно хорошее начало для меня, ценю это. У вас есть предложения по вопросу 1? - person JavaPotter; 16.03.2015
comment
Без проблем. Радоваться, веселиться. - person Alkis Kalogeris; 16.03.2015
comment
привет, я обновил свой исходный пост с изменениями кода, которые я сделал до сих пор. У меня проблемы с записью данных в новую книгу. Это ошибки, которые я получаю Exception в потоке main java.lang.NullPointerException в demo.poi.test.cellToString(test.java:80) в demo.poi.test.main(test.java:56) - person JavaPotter; 18.03.2015
comment
Хорошо, я обновил свой код некоторыми дополнительными комментариями для вашего удобства. Однако имейте в виду, что это выходит за рамки правил SO. Отладочные вопросы не действительны. Радоваться, веселиться - person Alkis Kalogeris; 18.03.2015