java使用POI识别excel的复选框插件

前言:

不知道小伙伴们有没有遇见过“要识别excel里的插件对象”的需求。一般情况来说,在软件项目开发的过程中这种需求一般不常见,因为在excel里面的内容完全可以通过线上来提交,比如使用form表单等形式来进行数据录入。但是在线下处理一些材料、数据等可能会遇到这样的问题。
我的这个需求就是线下遇到的,也并不是软件项目开发中的需求(附带讲:项目中的这种功能完全没有必要存在,因为实现这种需求的方式太有针对性了,还并不能保证它的正确性。总之,这种功能完全就是出力不讨好的典型)

问题描述:

问题背景是这样的,我们要做一个数据分析模型,然后甲方需要提供分析数据,将一个个excel数据表转化为一个一条条记录的记录表好用作模型分析。最后就是提供给我们的数据表是含带插件对象的excel表,因为之前没有读取过excel的插件对象,让我以为这种插件对象完全读取不了。后经查看文章发现有一种方式是可以读取的,可以依靠这种方式实现数据读取。

注:在这里要感谢一下前辈的这篇文章“在Java中的Apache POI读取Excel的复选框值(Reading Excel checkbox values in Java Apache POI)

下面给出实现经过和方式:

我们先来看下复选框或单选框长得什么样:
在这里插入图片描述
我们要做的就是要识别excel中,选择的是男或女、是或否。
目前只能通过代码实现对选择框的选中判断,返回true或false,以此来做识别判断

所需jar包:
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>
识别代码如下:
package com.yzw.exceldemo.excel;

import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * @author yzw
 */
public class ExcelObject {
    private static final String Workbook = "Workbook";

    public static void readCheckbox(String path) {
        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();
            }
        }
    }

    /**
     * 写个main方法来做一个测试
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("ReadExcelFile");
        //此处为我使用的一个线程用来存储每次复选框的识别列表(目前不需要)
        ObjectList.setCurrentFlag(new ArrayList());
        System.out.println("ReadCheckbox");
        readCheckbox("C:\\Users\\Administrator\\Desktop\\复选框测试.xls");
    }
}



然后,我们还需要写一个类来实现HSSFListener类,并重写processRecord方法,代码如下:

package com.yzw.exceldemo.excel;

import org.apache.poi.hssf.eventusermodel.HSSFListener;
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 java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author yzw
 */
public class EventExample implements HSSFListener {

    private final static Pattern P = Pattern.compile("\\[sid=0x000A.+?\\[0(\\d),");

    @Override
    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)) {
                        Matcher m = P.matcher(subRecord.toString());
                        if (m.find()) {
                            String checkBit = m.group(1);
                            if (checkBit.length() == 1) {
                                boolean checked = "1".equals(checkBit);
                                ObjectList.getCurrentFlag().add(checked);

                                System.out.println(ObjectList.getCurrentFlag().size()+"--------"+checked+"-----------"+checkBit);
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
    }
}

然后运行上面的main方法做一个测试,打印测试结果:
在这里插入图片描述
然后我们变动一下单选框,如下:
在这里插入图片描述
再次运行main方法,打印结果:
在这里插入图片描述
基于此,我们可以得出对应关系如下:

1----对应----男(true)
2----对应----女(true)
3----对应----是(true)
4----对应----否(true)

注意:我们在使用这种方式时,一定要注意对应关系,尤其是复选框或单选框较多时。

接下来我来贴出ObjectList类的实现,其实还是有很多方法来实现存储当前的识别列表集合:
package com.yzw.exceldemo.excel;

import java.util.List;

/**
 * @author yzw
 * 使用一个线程对当前的数据进行一个存储
 */
public class ObjectList {

    private static ThreadLocal currentUser = new ThreadLocal();

    public static void setCurrentFlag(List t) {
        currentUser.set(t);
    }

    public static List getCurrentFlag() {
        return (List) currentUser.get();
    }

    public static void removeCurrentFlag() {
        currentUser.remove();
    }
}

注意:在当前使用完后,一定要记得清除List的数据。
当前方式只支持xls格式的excel,如需要将xlsx文件转为xls文件的则可以参照 使用宏将xlsx格式文件批量转为xls格式文件 这篇文章

关于excel的读取和写入这里就不进行展示了,网上一大堆。

好了,小伙伴们!只要能获取到识别结果,那么接下来的实现方式就不需要在展示了吧。

今天的分享到此结束,如有更好的实现方式,麻烦您一定要告知我,感谢!
使用Java POIExcel时,可以使用`XSSF`模块的`XSSFClientAnchor`和`XSSFDrawing`类来插入复选框并打勾。 以下是一个示例代码,可以在第一行添加一个带有复选框的单元格: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; public class ExcelWriter { public static void main(String[] args) throws Exception { // Create a workbook XSSFWorkbook workbook = new XSSFWorkbook(); // Create a sheet XSSFSheet sheet = workbook.createSheet("Sheet1"); // Create a row XSSFRow row = sheet.createRow(0); // Create a cell with checkbox XSSFCell cell = row.createCell(0); cell.setCellValue("Select"); // Create a drawing canvas XSSFDrawing drawing = sheet.createDrawingPatriarch(); // Create an anchor and attach the checkbox to it XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 2, 2); XSSFSimpleShape shape = drawing.createSimpleShape(anchor); shape.setShapeType(FormControlType.CHECK_BOX); shape.setFillColor(IndexedColors.WHITE.getIndex()); shape.setLineStyleColor(IndexedColors.BLACK.getIndex()); // Check the checkbox shape.getCTShape().getOleObject().getFormData().setCheckboxState(true); // Save the workbook workbook.write(new FileOutputStream("test.xlsx")); workbook.close(); } } ``` 在上面的代码,我们使用`XSSFClientAnchor`类创建了一个锚点,并使用`XSSFDrawing`类创建了一个绘图工具。接下来,我们使用`XSSFSimpleShape`类创建了一个简单形状,并将其附加到锚点上。我们设置了形状类型为`CHECK_BOX`,并设置了填充颜色和线条颜色。最后,我们使用`getCTShape()`方法获取形状的CTShape实例,并使用`getOleObject()`方法获取OLE对象,从而设置复选框的状态为“选”。 执行上面的代码,您将在Excel文档看到一个带有复选框的单元格,并且该单元格已经被选
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值