本文共 6955 字,大约阅读时间需要 23 分钟。
该部分学习代码托管地址:https://gitee.com/imdongrui/study-poi
Apache POI是一个用于支持Java程序操作Excel文件的jar包
org.apache.poi poi 4.1.2 org.apache.poi poi-ooxml 4.1.2
使用poi导出Excel文件我们可以将其分为三个步骤:
我们将这几个步骤体现到代码中:
在创建时需要注意,Workbook有两种,分别是org.apache.poi.hssf.usermodel.HSSFWorkbook与org.apache.poi.xssf.usermodel.XSSFWorkbook,其中org.apache.poi.xssf.usermodel.HSSFWorkbook对应的是Office97-2003的早期Excel版本,org.apache.poi.xssf.usermodel.XSSFWorkbook对应的是Excel 2007以上的版本
不能简单地理解为HSSFWorkbook对应xls,XSSFWorkbook对应xlsx,因为单纯通过后缀不足以判断一个Excel文件是什么版本的,因为Excel在打开表格文件时,并没有严格要求后缀与版本对应,即使版本与后缀不对应,仍然可以打开使用,但却会影响poi的解析,这在程序开发时需要注意
/** * 生成工作簿实例 * * @return 工作簿实例 */public static Workbook createExcel() throws ClassNotFoundException, IllegalAccessException, InstantiationException { return (Workbook) Class.forName("org.apache.poi.hssf.usermodel.HSSFWorkbook").newInstance();}
/** * 创建工作表,多个Sheet则调用此函数多次 * * @param sheetName 工作表名称,若传null,则使用默认的名称 * @param titles 表头 * @param dataSet 数据集 * @param workbook 工作簿实例 * @return 工作表实例 */public static Sheet createSheet(String sheetName, String[] titles, String[][] dataSet, Workbook workbook) { // 创建Sheet实例 Sheet sheet = null == sheetName ? workbook.createSheet() : workbook.createSheet(sheetName); // 创建表头行,并依次向表头行的表格写入表头数据 Row row = sheet.createRow(0);// 创建数据航 for (int i = 0; i < titles.length; i++) { Cell cell = row.createCell(i);// 创建单元格 cell.setCellValue(titles[i]);// 写入数据 } // 循环写入数据集中的数据 int rows = dataSet.length; int cols = dataSet[0].length; // 依次处理数据行 for (int rowNum = 0; rowNum < rows; rowNum++) { Row tmpRow = sheet.createRow(rowNum + 1);//因为表头行占用一行,此处+1 // 依次处理数据列 for (int colNum = 0; colNum < cols; colNum++) { Cell cell = tmpRow.createCell(colNum); cell.setCellValue(dataSet[rowNum][colNum]); } } return sheet;}
/** * 输出Excel文件到指定路径 * * @param filePath 输出路径(含文件名) * @param workbook 当前工作簿实例 */public static void outputExcel(String filePath, Workbook workbook) throws IOException { OutputStream outputStream = new FileOutputStream(filePath); try { workbook.write(outputStream); } finally { outputStream.close(); }}
通过下面的调用步骤,可以在指定路径下创建一个test.xls文件,并写入我们需要的数据
String[] headers = { "编号", "姓名", "班级", "入学时间"};// students是一个Student列表,Student是一个简单的数据对象String[][] dataSet = ExcelUtils.list2Matrix(students, Student.class);Workbook workbook = ExcelUtils.createExcel();// 此处创建两个SheetExcelUtils.createSheet("student", headers, dataSet, workbook);ExcelUtils.createSheet("student2", headers, dataSet, workbook);ExcelUtils.outputExcel("D:\\test.xls", workbook);
/** * 将数据对象的List转换为字符串的二维数组 * * @param data 数据对象的List * @param tClass 数据对象的class * @param数据对象 * @return 二维数组 */public static String[][] list2Matrix(List data, Class tClass) throws IllegalAccessException { Field[] fields = tClass.getDeclaredFields(); String[][] dataSet = new String[data.size()][fields.length]; // 依次处理列表中的对象 for (int i = 0, len = data.size(); i < len; i++) { T t = data.get(i); // 依次获取对象声明的字段值,并存入dataSet中 for (int j = 0; j < fields.length; j++) { fields[j].setAccessible(true); Object value = fields[j].get(t); // 对Date类型的数据进行处理,其它类型数据有处理需求也可在此添加处理逻辑 if (value instanceof Date) { value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value); } dataSet[i][j] = value.toString(); } } return dataSet;}
导入Excel文件中的数据也可以分为两个步骤:
下面将步骤反映到代码中:
public enum ExcelType { HSSF("org.apache.poi.hssf.usermodel.HSSFWorkbook"), XSSF("org.apache.poi.xssf.usermodel.XSSFWorkbook"); ExcelType(String className) { this.className = className; } private String className; public String getClassName() { return className; }}
/** * 从指定路径下的文件创建工作簿实例 * @param path Excel文件路径 * @param type Excel文件的类型 * @return 工作簿实例 */public static Workbook createWorkbook(String path, ExcelType type) throws IOException { // 创建文件输入流 FileInputStream fileInputStream = new FileInputStream(path); // 根据Excel文件的类型,生成对应的工作簿实例 switch (type) { case HSSF: return new HSSFWorkbook(fileInputStream); case XSSF: return new XSSFWorkbook(fileInputStream); default: throw new RuntimeException(); }}
/** * 读取Sheet中的数据 * @param workbook 工作簿实例 * @param sheetNo 要读取的Sheet编号 * @param tClass 目标数据对象的class * @param目标数据对象 * @return 读取出来的目标数据对象列表 */public static List readSheet(Workbook workbook, int sheetNo, Class tClass) throws IllegalAccessException, InstantiationException, ParseException { List list = new ArrayList<>(); // 获取指定的Sheet实例 Sheet sheet = workbook.getSheetAt(sheetNo); Field[] fields = tClass.getDeclaredFields(); // 跳过表头,从第一行数据开始解析,sheet.getPhysicalNumberOfRows()获取当前Sheet中数据总行数 for (int i = 1, rowCount = sheet.getPhysicalNumberOfRows(); i < rowCount; i++) { Row row = sheet.getRow(i);// 获取指定行 T t = tClass.newInstance(); // 解析每行数据,row.getPhysicalNumberOfCells()获取当前行下单元格总数 for (int j = 0, cellCount = row.getPhysicalNumberOfCells(); j < cellCount; j++) { Cell cell = row.getCell(j);// 获取指定单元格 String strValue = cell.getStringCellValue(); fields[j].setAccessible(true); Class fieldClass = fields[j].getType(); // 按照各个字段类型,处理赋值 if (fieldClass == Integer.class || fieldClass == int.class) { fields[j].setInt(t, Integer.parseInt(strValue)); } else if (fieldClass == Boolean.class || fieldClass == boolean.class) { fields[j].setBoolean(t, Boolean.parseBoolean(strValue)); } else if (fieldClass == Double.class || fieldClass == double.class) { fields[j].setDouble(t, Double.parseDouble(strValue)); } else if (fieldClass == String.class) { fields[j].set(t, strValue); } else if (fieldClass == Date.class) { fields[j].set(t, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(strValue)); } } list.add(t); } return list;}
Workbook workbook = ExcelUtils.createWorkbook("D:\\test.xlsx", ExcelType.XSSF);Listlist = ExcelUtils.readSheet(workbook, 0, Student.class);list.forEach(student -> System.out.println(student.toString()));
《》
转载地址:http://zvtlf.baihongyu.com/