Reading Excel checkbox values in Java Apache POI

亡梦爱人 提交于 2019-12-12 16:55:23

问题


I have spent countless hours trying to find a solution to this. I have tried Apache POI, JExcel and JXLS but no where have I found code to successfully read checkbox (form control) values.

If anyone has found a working solution then it would be great if you could share it here. Thanks!

UPDATE

I have written code that reads the checkbox but it cannot determine whether it is checked or not.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SubRecord;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;

public class App {
    private static final String path = "C:\\test.xls";
    private static final String Workbook = "Workbook";

    private static void readExcelfile() {
        FileInputStream file = null;
        try {
            file = new FileInputStream(new File(path));

            // Get the workbook instance for XLS file
            HSSFWorkbook workbook = new HSSFWorkbook(file);

            // Get first sheet from the workbook
            HSSFSheet sheet = workbook.getSheetAt(0);

            // Iterate through each rows from first sheet
            Iterator<Row> rowIterator = sheet.iterator();
            while (rowIterator.hasNext()) {
                Row row = rowIterator.next();

                // For each row, iterate through each columns
                Iterator<Cell> cellIterator = row.cellIterator();
                while (cellIterator.hasNext()) {
                    Cell cell = cellIterator.next();

                    switch (cell.getCellType()) {
                    case Cell.CELL_TYPE_BOOLEAN:
                        System.out.print(cell.getBooleanCellValue() + "\t\t");
                        break;
                    case Cell.CELL_TYPE_NUMERIC:
                        System.out.print(cell.getNumericCellValue() + "\t\t");
                        break;
                    case Cell.CELL_TYPE_STRING:
                        System.out.print(cell.getStringCellValue() + "\t\t");
                        break;
                    }
                }
                System.out.println();
            }
            // file.close();
            // FileOutputStream out = new FileOutputStream(
            // new File(path));
            // workbook.write(out);
            // out.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (file != null)
                    file.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private static void readCheckbox() {
        FileInputStream file = null;
        InputStream istream = null;
        try {
            file = new FileInputStream(new File(path));
            POIFSFileSystem poifs = new POIFSFileSystem(file);
            istream = poifs.createDocumentInputStream(Workbook);
            HSSFRequest req = new HSSFRequest();
            req.addListenerForAllRecords(new EventExample());
            HSSFEventFactory factory = new HSSFEventFactory();
            factory.processEvents(req, istream);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (file != null)
                    file.close();
                if (istream != null)
                    istream.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("ReadExcelFile");
        readExcelfile();
        System.out.println("ReadCheckbox");
        readCheckbox();
    }
}

class EventExample implements HSSFListener {

    public void processRecord(Record record) {
        switch (record.getSid()) {
        case ObjRecord.sid:
            ObjRecord objRec = (ObjRecord) record;
            List<SubRecord> subRecords = objRec.getSubRecords();
            for (SubRecord subRecord : subRecords) {
                if (subRecord instanceof CommonObjectDataSubRecord) {
                    CommonObjectDataSubRecord datasubRecord = (CommonObjectDataSubRecord) subRecord;
                    if (datasubRecord.getObjectType() == CommonObjectDataSubRecord.OBJECT_TYPE_CHECKBOX) {
                        System.out.println("ObjId: "
                                + datasubRecord.getObjectId() + "\nDetails: "
                                + datasubRecord.toString());
                    }
                }
            }
            break;
        }
    }
}

回答1:


Sorry for the late reply, but I ran into the same. I found a trick to determine the checkbox state.

In your example you ar looping over the SubRecords and you examine the CommonObjectDataSubRecord. But the value for the checkbox can be found in the one of the SubRecord.UnknownSubRecord. This is unfortunately a private class so you cannot call any method on it, but the toString() reveals the data, and with a little regex the value can be found. So using the code below I managed to retrieve the state of the checkbox:

Pattern p = Pattern.compile("\\[sid=0x000A.+?\\[0(\\d),");
if (!(subRecord instanceof CommonObjectDataSubRecord)) {
    Matcher m = p.matcher(subRecord.toString());
    if (m.find()) {
        String checkBit = m.group(1);
        if (checkBit.length() == 1) {
            boolean checked = "1".equals(checkBit);
            checkBox.setChecked(checked);
        }
    }
}

Now my challenge is to retrieve the checkbox value in a xlsx file...



来源:https://stackoverflow.com/questions/30227873/reading-excel-checkbox-values-in-java-apache-poi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!