您当前的位置:首页 > 网站建设 > 网站维护
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery |

Apache

51自学网 2022-07-22 18:46:39
  网站维护

poi介绍:

Apache POI是用Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。

POI使用到的相关maven依赖坐标如下:

<dependency>  <groupId>org.apache.poi</groupId>  <artifactId>poi</artifactId>  <version>3.14</version></dependency><dependency>  <groupId>org.apache.poi</groupId>  <artifactId>poi-ooxml</artifactId>  <version>3.14</version></dependency>

POI的相关操作结果

HSSF - 提供读写Microsoft Excel XLS格式档案的功能XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能HWPF - 提供读写Microsoft Word DOC格式档案的功能HSLF - 提供读写Microsoft PowerPoint格式档案的功能HDGF - 提供读Microsoft Visio格式档案的功能HPBF - 提供读Microsoft Publisher格式档案的功能HSMF - 提供读Microsoft Outlook格式档案的功能

1、POI操作入门案例

1.1、从Excel文件读取数据1

使用POI可以从一个已经存在的Excel文件中读取数据

前提需要建立一个需要读取的表格数据进行读取

/** * 使用poi读取表格数据 * @throws Exception */@Testpublic void test1() throws Exception {    // 1、加载指定的文件进行读取    XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream("C://Users//zhong//Desktop//poi.xlsx"));    // 2、读取表格中的Sheet页,通过索引决定    XSSFSheet sheetAt = excel.getSheetAt(0);    // 3、读取Sheet页中的行数据    for (Row row : sheetAt) {        // 4、读取每一行数据的单元格数据(如果涉及到类型装转换的可能出现报错消息,后期通过代码进行判断即可)        for (Cell cell : row) {            System.out.print(cell+"   ");        }        System.out.println();    }    // 5、关闭读取文件的流    excel.close();}

输出结果如下:

姓名   省份   城市   
张三   广东   高州   
李四   四川   成都   

POI操作Excel表格封装了几个核心对象:

XSSFWorkbook:工作簿
XSSFSheet:工作表
Row:行
Cell:单元格

1.2、从Excel文件读取数据2

还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象,代码如下:

/** * 使用poi读取文件的第二种方式 * @throws Exception */@Testpublic void test2() throws Exception {    // 1、加载指定的文件进行读取    XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream("C://Users//zhong//Desktop//poi.xlsx"));    // 2、读取表格中的Sheet页,通过索引决定    XSSFSheet sheetAt = excel.getSheetAt(0);    // 3、获取当前工作表中最后一个行号,注意行号是从0开启的    int lastRowNum = sheetAt.getLastRowNum();    // 4、遍历获取到的行号    for (int i = 0; i <= lastRowNum; i++) {        // 5、根据行号获取到每一行的数据        XSSFRow row = sheetAt.getRow(i);        // 6、获取到当前最后一个单元格索引        short lastCellNum = row.getLastCellNum();        // 7、遍历当前的单元格获取到具体的数据        for (int j = 0; j < lastCellNum; j++) {            // 获取到单元格的对象            XSSFCell cell = row.getCell(j);            // 输出获取到的数据            System.out.print(cell + "   ");        }        System.out.println();    }    // 8、释放资源    excel.close();}

1.3、向Excel文件写入数据

使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘

/** * poi写出数据到磁盘 */@Testpublic void test3() throws Exception {    // 1、创建工作簿    XSSFWorkbook excel = new XSSFWorkbook();    // 2、创建工作簿中的表对象    XSSFSheet sheet = excel.createSheet("创建表");    // 3、创建第一行(表头)    XSSFRow row1 = sheet.createRow(0);    // 4、在行中创建单元格数据    row1.createCell(0).setCellValue("姓名");    row1.createCell(1).setCellValue("省份");    row1.createCell(2).setCellValue("城市");    row1.createCell(3).setCellValue("年龄");    // 5、创建第二行    XSSFRow row2 = sheet.createRow(1);    // 6、创建第6行的数据    row2.createCell(0).setCellValue("张三");    row2.createCell(1).setCellValue("辽宁");    row2.createCell(2).setCellValue("上海");    row2.createCell(3).setCellValue("50");    // 7、创建一个字节输出流,将数据保存到本地    FileOutputStream fileOutputStream = new FileOutputStream(new File("C://Users//zhong//Desktop//aaa.xlsx"));    excel.write(fileOutputStream);    fileOutputStream.flush();    // 8、关闭输出    excel.close();    System.out.println("数据导出成功");}

2、使用POI批量导入数据到MySQL数据库

创建一个数据库的表t_ordersetting

-- auto-generated definitioncreate table t_ordersetting(    id           int auto_increment        primary key,    orderDate    date null comment '约预日期',    number       int  null comment '可预约人数',    reservations int  null comment '已预约人数')    charset = utf8;

批量导入预约设置信息操作过程:

1、点击模板下载按钮下载Excel模板文件

2、将预约设置信息录入到模板文件中

3、点击上传文件按钮将录入完信息的模板文件上传到服务器

4、通过POI读取上传文件的数据并保存到数据库

创建对应的实体类

public class OrderSetting implements Serializable{    private Integer id ;    private Date orderDate;//预约设置日期    private int number;//可预约人数    private int reservations ;//已预约人数    public OrderSetting() {    }    public OrderSetting(Date orderDate, int number) {        this.orderDate = orderDate;        this.number = number;    }}

2.1、创建导入数据的Excel模板文件

目的是为了统一管理导入的数据格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbCEXvYt-1655542646539)(images/image-20220618142527340.png)]

修改页面提供一个下载批量导入数据的模板按钮

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7OlfHCQJ-1655542646540)(images/image-20220618143241355.png)]

//下载模板文件downloadTemplate(){    window.location.href="../../template/ordersetting_template.xlsx" rel="external nofollow" ;}

文件上传前端代码实现

<el-upload action="/ordersetting/upload.do"           name="excelFile"           :show-file-list="false"           :on-success="handleSuccess"           :before-upload="beforeUpload">    <el-button type="primary">上传文件</el-button></el-upload>

提交函数

// 上传之前进行文件格式校验beforeUpload(file){    const isXLS = file.type === 'application/vnd.ms-excel';    if(isXLS){        return true;    }    const isXLSX = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';    if (isXLSX) {        return true;    }    this.$message.error('上传文件只能是xls或者xlsx格式!');    return false;},// 上传成功提示handleSuccess(response, file) {    if(response.flag){        this.$message({            message: response.message,            type: 'success'        });    }else{        this.$message.error(response.message);    }    console.log(response, file, fileList);},

2.2、批量上传文件的后端代码编写

关于上传文件一般网上都会有很多的工具类可以下载使用,也就是别人将已经封装好的代码拿出来分享给大家使用的

package com.zcl.utils;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import org.apache.poi.hssf.usermodel.HSSFWorkbook;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.XSSFWorkbook;import org.springframework.web.multipart.MultipartFile;public class POIUtils {    private final static String xls = "xls";    private final static String xlsx = "xlsx";    private final static String DATE_FORMAT = "yyyy/MM/dd";    /**     * 读入excel文件,解析后返回     * @param file     * @throws IOException     */    public static List<String[]> readExcel(MultipartFile file) throws IOException {        //检查文件        checkFile(file);        //获得Workbook工作薄对象        Workbook workbook = getWorkBook(file);        //创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回        List<String[]> list = new ArrayList<String[]>();        if(workbook != null){            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){                //获得当前sheet工作表                Sheet sheet = workbook.getSheetAt(sheetNum);                if(sheet == null){                    continue;                }                //获得当前sheet的开始行                int firstRowNum  = sheet.getFirstRowNum();                //获得当前sheet的结束行                int lastRowNum = sheet.getLastRowNum();                //循环除了第一行的所有行                for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){                    //获得当前行                    Row row = sheet.getRow(rowNum);                    if(row == null){                        continue;                    }                    //获得当前行的开始列                    int firstCellNum = row.getFirstCellNum();                    //获得当前行的列数                    int lastCellNum = row.getPhysicalNumberOfCells();                    String[] cells = new String[row.getPhysicalNumberOfCells()];                    //循环当前行                    for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){                        Cell cell = row.getCell(cellNum);                        cells[cellNum] = getCellValue(cell);                    }                    list.add(cells);                }            }            workbook.close();        }        return list;    }    //校验文件是否合法    public static void checkFile(MultipartFile file) throws IOException{        //判断文件是否存在        if(null == file){            throw new FileNotFoundException("文件不存在!");        }        //获得文件名        String fileName = file.getOriginalFilename();        //判断文件是否是excel文件        if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){            throw new IOException(fileName + "不是excel文件");        }    }    public static Workbook getWorkBook(MultipartFile file) {        //获得文件名        String fileName = file.getOriginalFilename();        //创建Workbook工作薄对象,表示整个excel        Workbook workbook = null;        try {            //获取excel文件的io流            InputStream is = file.getInputStream();            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象            if(fileName.endsWith(xls)){                //2003                workbook = new HSSFWorkbook(is);            }else if(fileName.endsWith(xlsx)){                //2007                workbook = new XSSFWorkbook(is);            }        } catch (IOException e) {            e.printStackTrace();        }        return workbook;    }    public static String getCellValue(Cell cell){        String cellValue = "";        if(cell == null){            return cellValue;        }        //如果当前单元格内容为日期类型,需要特殊处理        String dataFormatString = cell.getCellStyle().getDataFormatString();        if(dataFormatString.equals("m/d/yy")){            cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue());            return cellValue;        }        //把数字当成String来读,避免出现1读成1.0的情况        if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){            cell.setCellType(Cell.CELL_TYPE_STRING);        }        //判断数据的类型        switch (cell.getCellType()){            case Cell.CELL_TYPE_NUMERIC: //数字                cellValue = String.valueOf(cell.getNumericCellValue());                break;            case Cell.CELL_TYPE_STRING: //字符串                cellValue = String.valueOf(cell.getStringCellValue());                break;            case Cell.CELL_TYPE_BOOLEAN: //Boolean                cellValue = String.valueOf(cell.getBooleanCellValue());                break;            case Cell.CELL_TYPE_FORMULA: //公式                cellValue = String.valueOf(cell.getCellFormula());                break;            case Cell.CELL_TYPE_BLANK: //空值                cellValue = "";                break;            case Cell.CELL_TYPE_ERROR: //故障                cellValue = "非法字符";                break;            default:                cellValue = "未知类型";                break;        }        return cellValue;    }}

2.2.1、创建批量上传控制器

这里使用的dubbo远程调用了接口方法

/** * 项目名称:health_parent * 描述:预约管理控制器 * * @author zhong * @date 2022-06-18 14:50 */@RestController@RequestMapping("/ordersetting")public class OrderSettingController {    /**     * 远程调用预约管理的服务接口     */    @Reference    private OrderSettingService orderSettingService;    /**     * 文件上传,实现预约管理的批量导入     * @param excelFile     * @return     */    @RequestMapping("/upload")    public Result upload(@RequestParam("excelFile") MultipartFile excelFile){        try {            // 1、使用工具类解析上传的数据            List<String[]> list = POIUtils.readExcel(excelFile);            // 将读取的表格数据转换为表格预约对象数据            List<OrderSetting> data = new ArrayList<>();            // 2、处理解析的数据            for (String[] strings : list) {                // 获取到导入数据行的第一个单元格(预约时间)                String orderSate = strings[0];                // 获取到导入数据行的第二个单元格(预约姓名)                String number = strings[1];                // 将重新获取到的数据添加到预约集合中                OrderSetting orderSetting = new OrderSetting(new Date(orderSate), Integer.parseInt(number));                data.add(orderSetting);            }            // 2、通过dubbo远程调用服务实现数据批量导入到数据库            orderSettingService.add(data);        } catch (IOException e) {            e.printStackTrace();            return new Result(false, MessageConstant.IMPORT_ORDERSETTING_FAIL);        }        return new Result(true, MessageConstant.IMPORT_ORDERSETTING_SUCCESS);    }}

2.2.2、创建批量上传的接口实现类

package com.zcl.service.impl;import com.alibaba.dubbo.config.annotation.Service;import com.itheima.pojo.OrderSetting;import com.zcl.dao.OrderSettingDao;import com.zcl.service.OrderSettingService;import org.springframework.transaction.annotation.Transactional;import java.util.List;/** * 项目名称:health_parent * 描述:预约管理接口实现类 * * @author zhong * @date 2022-06-18 15:09 */@Service(interfaceClass = OrderSettingService.class)@Transactionalpublic class OrderSettingImpl implements OrderSettingService {    /**     * 注入保存数据     */    @Autowired    private OrderSettingDao orderSettingDao;    /**     * 批量上传业务实现     * @param data     */    @Override    public void add(List<OrderSetting> data) {        // 判断集合数据是否为空        if(data != null && data.size() > 0){            // 判断当前日期是否已经进行了预约设置            for (OrderSetting datum : data) {                // 根据日期查询预约消息                long count = orderSettingDao.findCountByOrderDate(datum.getOrderDate());                if(count > 0){                    // 已进行预约管理,执行更新操作                    orderSettingDao.editNumberByOrderDate(datum);                }else{                    // 添加预约设置                    orderSettingDao.add(datum);                }            }        }else{        }    }}

2.2.3、创建数据访问层接口和映射文件

package com.zcl.dao;import com.itheima.pojo.OrderSetting;import java.util.Date;/** * 项目名称:health_parent * 描述:预约管理数据访问层 * * @author zhong * @date 2022-06-18 15:13 */public interface OrderSettingDao {    /**     * 添加预约数据     * @param orderSetting     */    void add(OrderSetting orderSetting);    /**     * 修改预约数据     * @param orderSetting     */    void editNumberByOrderDate(OrderSetting orderSetting);    /**     * 查询预约数据的总数     * @param orderDate     * @return     */    long findCountByOrderDate(Date orderDate);}

数据访问层映射文件编写SQL语句

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.zcl.dao.OrderSettingDao">    <!--添加预约嘻嘻嘻-->    <insert id="add" parameterType="com.itheima.pojo.OrderSetting">        insert into t_ordersetting (orderDate,number,reservations)        values (#{orderDate},#{number},#{reservations});    </insert>    <!--根据日期修改预约信息-->    <update id="editNumberByOrderDate" parameterType="com.itheima.pojo.OrderSetting">        update t_ordersetting        set number = #{number}        where orderDate = #{orderDate}    </update>    <!--根据日期查询数据-->    <select id="findCountByOrderDate" parameterType="date" resultType="java.lang.Long">        select count(id)        from t_ordersetting        where orderDate = #{orderDate}    </select></mapper>

3、批量导入数据测试

在上传模板上制作数据,然后进行导入,先导入新的数据再导入修改后日期不变的数据再次上传数据


下载地址:
详解ZABBIX监控ESXI主机的问题
k8s&nbsp;series初级calico使用介绍
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1