博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
来,通过 Excel 来认识神器——POI
阅读量:1959 次
发布时间:2019-04-27

本文共 8507 字,大约阅读时间需要 28 分钟。

1、POI是什么

Apache POI - the Java API for Microsoft Documents,顾名思义,Apache的三方包,用来操作微软office文档的,多数时候用来操作excel,所以这里就以excel方面来说明。

需要引入两个包,maven地址如下(version 3.9):

org.apache.poi
poi
3.9
org.apache.poi
poi-ooxml
3.9

POI的组件列表中,针对excel的主要是HSSF和XSSF组件,前者针对97-2007的通用版excel,即后缀xls;后者针对2007或更高版的excel,即后缀xlsx。官方概要如下:

HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.

2、POI核心类

面向对象面向对象,既然如此,自然去找找一些能表示excel中内容的类。

2.1 工作簿 Workbook

创建或维护Excel工作簿的所有类的超接口,Workbook,属于org.apache.poi.ss.usermodel包。其下有两个实现类:

  • HSSFWorkbook : 有读取.xls 格式和写入Microsoft Excel文件的方法。它与微软Office97-2003版本兼容
  • XSSFWorkbook : 有读写Microsoft Excel和OpenOffice的XML文件的格式.xls或.xlsx的方法。它与MS-Office版本2007或更高版本兼容

所以在针对不同版本的excel时,需要对应以上使用不同的Workbook。构造函数中,常用的:

HSSFWorkbook

HSSFWorkbook()HSSFWorkbook(java.io.InputStream s)

XSSFWorkbook

XSSFWorkbook()XSSFWorkbook(java.io.File file)XSSFWorkbook(java.io.InputStream is)

2.2 标签页 Sheet

HSSFSheetXSSFSheet 都是Sheet接口的实现类,Sheet可以使用Workbook的两个方法获得:

workbook.createSheet();workbook.createSheet(String sheetName);

2.3 行 Row

同理,Row是 HSSFRowXSSFRow 的接口,通过Sheet获取:

sheet.createRow(int rownum);

2.4 单元格 Cell

同理,Cell是 HSSFCellXSSFCell 的接口,通过Row获取:

row.createCell(int column);row.createCell(int column, int type);

3、创建和读取

其实如果能理解面向对象,就很简单了,另外包括字体,公式,超链接等,都有对应的封装类,此处只提出了核心的几个,需要了解更多的需要自行展开。

例子的话,直接从别人教程里摘出来吧,另,读取的workbook,可以debug瞅瞅内容。

3.1 创建空白工作簿

import java.io.*;import org.apache.poi.xssf.usermodel.*;public class CreateWorkBook {   public static void main(String[] args)throws Exception    {      XSSFWorkbook workbook = new XSSFWorkbook();       FileOutputStream out = new FileOutputStream(      new File("createworkbook.xlsx"));      workbook.write(out);      out.close();      System.out.println("      createworkbook.xlsx written successfully");   }}

3.2 打开现有的工作簿

import java.io.*;import org.apache.poi.xssf.usermodel.*;public class OpenWorkBook{   public static void main(String args[])throws Exception   {       File file = new File("openworkbook.xlsx");      FileInputStream fIP = new FileInputStream(file);      XSSFWorkbook workbook = new XSSFWorkbook(fIP);      if(file.isFile() && file.exists())      {         System.out.println(         "openworkbook.xlsx file open successfully.");      }      else      {         System.out.println(         "Error to open openworkbook.xlsx file.");      }   }}

3.3、任意对象List转至为Excel文档

可用注解定义标签名和列名,写了个方法,可以将某个类的List转换为对应的Excel文档,列名如果在不使用注解的情况下默认为属性名:

类:

@Excel(name = "学生标签页")public class Student {    @Excel(name = "姓名")    private String name;    private boolean male;    @Excel(name = "身高")    private int height;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public boolean isMale() {        return male;    }    public void setMale(boolean male) {        this.male = male;    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }}

测试方法:

public static void main(String[] args) {    List
list = new ArrayList
(); Student student1 = new Student(); student1.setName("小红"); student1.setMale(false); student1.setHeight(167); Student student2 = new Student(); student2.setName("小明"); student2.setMale(true); student2.setHeight(185); list.add(student1); list.add(student2); File file = new File("C:/Users/Dulk/Desktop/1314.xls"); createExcel(list, file);}

输出结果:

注解:

import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface Excel {    public String name() default "";}

方法:

import org.apache.log4j.Logger;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 java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;public class ExcelUtil {    private static Logger log = Logger.getLogger(ExcelUtil.class);    public static Workbook gainWorkbook(File file) throws ExcelException {        if (!isExcel(file)) {            throw new ExcelException("文件不是Excel类型");        }        if (!file.exists()) {            try {                OutputStream os = new FileOutputStream(file);                Workbook workbook = isOlderEdition(file) ? new HSSFWorkbook() : new XSSFWorkbook();                workbook.write(os);                log.debug("文件不存在,新建该Excel文件");                os.close();            } catch (FileNotFoundException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }        try {            InputStream is = new FileInputStream(file);            return isOlderEdition(file) ? new HSSFWorkbook(is) : new XSSFWorkbook(is);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return null;    }    private static boolean isOlderEdition(File file) {        return file.getName().matches(".+\\.(?i)xls");    }    private static boolean isExcel(File file) {        String fileName = file.getName();        String regXls = ".+\\.(?i)xls";        String regXlsx = ".+\\.(?i)xlsx";        return fileName.matches(regXls) || fileName.matches(regXlsx);    }    public static 
Workbook createExcel(List
list, File file) { String sheetName = "default"; if (list.size() == 0) { return null; } Workbook workbook = null; try { Class clazz = list.get(0).getClass(); Field[] fields = clazz.getDeclaredFields(); if (clazz.isAnnotationPresent(Excel.class)) { Excel excel = (Excel) clazz.getAnnotation(Excel.class); sheetName = excel.name(); } workbook = gainWorkbook(file); Sheet sheet = workbook.createSheet(sheetName); Row line = sheet.createRow(0); for (int k = 0; k < fields.length; k++) { Cell cell = line.createCell(k); String columnName = fields[k].getName(); if (fields[k].isAnnotationPresent(Excel.class)) { Excel excel = fields[k].getAnnotation(Excel.class); columnName = excel.name(); } cell.setCellValue(columnName); } for (int i = 1; i <= list.size(); i++) { Row row = sheet.createRow(i); for (int j = 1; j <= fields.length; j++) { Cell cell = row.createCell(j - 1); String fieldName = fields[j - 1].getName(); String fieldFirstLetterUpper = fieldName.substring(0, 1).toUpperCase(); String prefix = "get"; if ("boolean".equals(fields[j - 1].getType().getName())) { prefix = "is"; } String methodName = prefix + fieldFirstLetterUpper + fieldName.substring(1); Method method = clazz.getMethod(methodName); cell.setCellValue(String.valueOf(method.invoke(list.get(i - 1)))); } } log.debug("List读入完毕"); OutputStream os = new FileOutputStream(file); workbook.write(os); os.close(); } catch (ExcelException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return workbook; }}

参考链接:

作者:Dulk

来源:

近期热文推荐:

1.

2.

3.

4.

5.

觉得不错,别忘了随手点赞+转发哦!

转载地址:http://ytjsf.baihongyu.com/

你可能感兴趣的文章
为什么执行 x in range(y) 如此快?
查看>>
看完这篇文章你还不理解 Python 装饰器,只有一种可能...
查看>>
Python干货:表达式 i += x 与 i = i + x 等价吗?
查看>>
有了这些 Chrome 插件,效率提升10倍(建议收藏)
查看>>
Python 编码错误的本质原因
查看>>
Python 开发者都会遇到的错误:UnboundLocalError
查看>>
用 Python 送“爱心”
查看>>
理解HTTPS为什么安全前,先看看这些东西
查看>>
只有1%的程序员搞懂过浮点数陷阱
查看>>
Erlang 之父 Joe Armstrong 去世
查看>>
一名 Google 工程师的大数据处理经验
查看>>
30分钟学会pyecharts数据可视化
查看>>
从一个骗子身上学到的
查看>>
关于Python爬虫,这里有一条高效的学习路径
查看>>
Python学习指南,看这篇清晰多了!
查看>>
命名难,难于上青天
查看>>
史上最烂项目:苦撑12年,600多万行代码...
查看>>
没钱没公司,怎么做一款付费产品
查看>>
查询亿级数据毫秒级返回!Elasticsearch 是如何做到的?
查看>>
FastAPI 构建 API 服务,究竟有多快?
查看>>