poi学习

HSSF是针对2007以前的版本即xls, XSSF是针对2007版本以后的即xlsx

读取excel的demo

demo1:在resource下面创建了excel2.xslx

package com.xiaofeifei.poi.read;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;

public class Demo1 {

    public static void main(String[] args) {
        Demo1 demo = new Demo1();
        InputStream inputStream = null;
        XSSFWorkbook workbook = null;

        try {
            inputStream = demo.getClass().getResourceAsStream("/excel2.xlsx");
            // 获取工作薄
            workbook = new XSSFWorkbook(inputStream);
            // 获取工作表
            XSSFSheet sheet = workbook.getSheetAt(0);

            // 获取行
            for (Row row : sheet) {
                for(Cell cell : row) {
                    //获取单元格中的内容:
                    String value = cell.getStringCellValue();
                    System.out.println(value);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {

            try {
                inputStream.close();
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

demo2 将数据写到excel中

package com.xiaofeifei.poi.write;

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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;

public class Demo2 {

    public static void main(String[] args) {

        // 1.创建工作薄
        XSSFWorkbook workbook = new XSSFWorkbook();

        // 2.创建工作表
        XSSFSheet sheet = workbook.createSheet("创建工作表");

        // 3.创建行
        XSSFRow row = sheet.createRow(0);
        // 创建单元格
        row.createCell(0).setCellValue("王二");
        row.createCell(1).setCellValue("王二");

        // 创建一个输出流
        URL resource = Demo2.class.getResource("/");
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(new File(resource.getPath()+"/excel3.xlsx"));
            workbook.write(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

将excel中的数据导入到数据库:

 <dependencies>
        <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>

        <!-- mysql 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.26</version>
            <scope>compile</scope>
        </dependency>
        <!-- druid 连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.9</version>
        </dependency>
    </dependencies>

做一个excel,有边框线,合并单元格,行高列宽,对齐方式,字体

package com.xiaofeifei.poi.write;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

//导出一个excel,合并单元格,行高列宽,对齐方式,字体
public class POIDemo4 {

    public static void main(String[] args) throws Exception {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("由样式的sheet");
        // 创建首行即大标题的样式
        // 设置是否有边框
        CellStyle bigTitleRowStyle = workbook.createCellStyle();
        // poi分别提供了四个方向的边框,没有所有方向边框的方法
        bigTitleRowStyle.setBorderLeft(CellStyle.BORDER_THIN);
        bigTitleRowStyle.setBorderTop(CellStyle.BORDER_THIN);
        bigTitleRowStyle.setBorderBottom(CellStyle.BORDER_THIN);
        bigTitleRowStyle.setBorderRight(CellStyle.BORDER_THIN);
        // 设置对齐方式:水平对齐,垂直对齐
        bigTitleRowStyle.setAlignment(CellStyle.ALIGN_CENTER);
        bigTitleRowStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        // 创建字体
        Font font = workbook.createFont();
        font.setFontName("黑体");
        font.setFontHeightInPoints((short)18);
        // 把字体放入到样式中
        bigTitleRowStyle.setFont(font);

        Row bigTitleRow = sheet.createRow(0);
        bigTitleRow.setHeightInPoints(42);
        for(int i = 0;i < 5; i++) {
            Cell cell = bigTitleRow.createCell(i);
            cell.setCellStyle(bigTitleRowStyle);
        }
        // 设置合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,4)); // int firstRow起始行,lastRow结束行,firstCol 开始列 lastCol结束列
        // 向单元格中放一句话:用户信息数据
        sheet.getRow(0).getCell(0).setCellValue("用户信息数据");

        // 创建小标题样式
        CellStyle littleTitleRowStyle = workbook.createCellStyle();
        // 将上面的样式克隆下来
        littleTitleRowStyle.cloneStyleFrom(bigTitleRowStyle);
        // 标题的字体和首行不一样,单独再创建字体
        Font littleFont = workbook.createFont();
        littleFont.setFontName("黑体");
        littleFont.setFontHeightInPoints((short)18);
        littleFont.setBold(true); //字体设置加粗
        // 把字体放入到样式中
        littleTitleRowStyle.setFont(font);
        String[] littleTitles = new String[] {"编号","姓名","手机号","入职时间","先住地址"};
        Row littleTitleRow = sheet.createRow(1);
        littleTitleRow.setHeightInPoints(31.5F);
        for(int i = 0; i < littleTitles.length; i++) {
            Cell cell = littleTitleRow.createCell(i);
            cell.setCellValue(littleTitles[i]);
            cell.setCellStyle(littleTitleRowStyle);
        }



        // 内容样式
        CellStyle contentRowStyle = workbook.createCellStyle();
        contentRowStyle.cloneStyleFrom(littleTitleRowStyle);
        contentRowStyle.setAlignment(CellStyle.ALIGN_LEFT);
        // 标题的字体和首行不一样,单独再创建字体
        Font contentFont = workbook.createFont();
        contentFont.setFontName("宋体");
        contentFont.setFontHeightInPoints((short)12);
        contentFont.setBold(false); //字体设置不加粗
        String[] datas = new String[] {"1","张三","111","2021-01-30","天堂"};
        Row dataRow1 = sheet.createRow(2);
        for(int i = 0; i < datas.length; i++) {
            Cell cell = dataRow1.createCell(i);
            cell.setCellValue(datas[i]);
            cell.setCellStyle(contentRowStyle);
        }
        workbook.write(new FileOutputStream("style.xlsx"));

    }
}

由于样式浪费了大量精力,我们可以首先创建好模板,我们只向模板中放数据就可以了

我们直接将上述生成的excel中从第三行删除作为模板,我们写入数据

package com.xiaofeifei.controller;

import com.xiaofeifei.model.Employee;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
public class ExportExcelController {

    @GetMapping("/download-excel")
    public void downLoadXlxsByPoiWithTemplate(HttpServletResponse response) throws Exception{
        File rootFile = new File(ResourceUtils.getURL("classpath:").getPath());
        File template = new File(rootFile, "style_template.xlsx"); //在resources 文件夹下放了模板
        XSSFWorkbook workbook = new XSSFWorkbook(template);
        XSSFSheet sheet = workbook.getSheetAt(0);
        int rowIndex = 2;
        Cell cell = null;
        List<Employee> employees = getEmployees();
        Employee employee = null;
        int size = employees.size();
        // 对于单元格的样式,我们可以获取在模板中第二个sheet页中写好一个单元格的样式,我们直接复制
        Sheet sheet1 = workbook.getSheetAt(1);
        Row row1 = sheet1.getRow(0);
        Cell templateCell = row1.getCell(0);
        CellStyle templateCellCellStyle = templateCell.getCellStyle();

        for(int i = 0; i < size; i++) {
            Row row = sheet.createRow(i + rowIndex);
            employee = employees.get(i);
            cell = row.createCell(0);
            cell.setCellValue(employee.getId());
            cell.setCellStyle(templateCellCellStyle);

            cell = row.createCell(1);
            cell.setCellValue(employee.getUserName());
            cell.setCellStyle(templateCellCellStyle);

             cell = row.createCell(2);
             cell.setCellValue(employee.getUserPhone());
            cell.setCellStyle(templateCellCellStyle);

             cell = row.createCell(3);
             cell.setCellValue(employee.getDate());
            cell.setCellStyle(templateCellCellStyle);

            cell = row.createCell(4);
            cell.setCellValue(employee.getAddress());
            cell.setCellStyle(templateCellCellStyle);
        }
        // 把第二个sheet删除掉
        workbook.removeSheetAt(1);
        String filename ="员工数据.xlsx";
        response.setHeader("content-disposition","attachement;filename=" + new String(filename.getBytes(),"ISO8859-1"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        workbook.write(response.getOutputStream());
    }

    private List<Employee> getEmployees() {
        List<Employee> employees = new ArrayList<>();
        Employee employee = null;
        for(int i = 1; i <= 2; i++) {
            employee = new Employee();
            employee.setId(i);
            employee.setDate(new Date());
            employee.setAddress("nihao");
            employee.setUserName("zhangshan");
            employee.setUserPhone("1111");
            employees.add(employee);
        }
        return employees;
    }


}

在poi中根据模板做用户信息明细

 上述图片比较特殊:1、位置比较特殊,设计合并单元格,从第二行开始到第五行从第三列开始到第四列 2、数据比较特殊,是图片

 现在处理照片,拿到图片

用patriarch 控制图片的写入和clientanchor指定图片的位置

 注意XSSFClientAnchor 有8各参数,各个参数的含义是,后四个参数的含义是:起始列起始行到结束列结束行,第一个参数图片左上角表示偏离x轴多少,第二个参数表示图片左上角偏离y轴多少,第三个参数表示图片右下角偏x轴多少,第四个参数表示图片右下角偏离y轴多少,偏离的单位是英式公式单位,1厘米等于360000

 虽然我们结束行5结束列为4,但是

这样写完会造成无法填充满 

 所以我们要添加一行

 poi写计算的公式:根据入职时间 计算出工作时间

 然后直接将复制上述函数公式

 poi支持哪些函数公式,可以去官网查,有的函数官网没有,自己可以试试

 当然用代码设置对应的函数完全没有必要,可以函数放到对应的模板中,即直接设置单元格的函数

自定义数据引擎:当某个单元格位置发生变动,我们的代码就要变动,例如手机号本来要填3行3列的单元格,现在要改为4行三列,我们用数据引擎就可以解决

 

 

 

 

 

 百万数据导出:

 操作高版本的excel本质就是操作xml

new woorkbook 这种方式其实用的是dom4j的方式

 

 

 创建一个存储过程,用来造数据,自定义分号原因,执行分号就自动提交了

 百万数据导出:不能使用模板和太多的样式,每个sheet数据不超过100万行

 

 

 

 百万级数据导入excel

 基于事件驱动的

 

 

 

 

poi操作word

 对于一个word文档,另存为html,就自动生成了相关的html文档

然后编辑html文件,将对应的内容去掉

 

这样就有了与word一样样式的网页,poi操作word和excel类似,用模板

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值