Apache-POI的基本使用
前言
很多时候,一个软件应用程序需要生成Microsoft Excel文件格式的报告。有时,一个应用程序甚至希望将Excel文件作为输入数据。例如,一个公司开发的应用程序将财务部门需要所有输出生成自己的Excel。
任何Java程序员愿意将MS Office文件的输出,可以使用预定义和只读API来做到。
什么是Apache POI?
- Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS Office文档进行解码。
- 下载地址 http://poi.apache.org/
Apache POI组件说明
Apache POI包含类和方法,来将MS Office所有OLE 2文档复合。此API组件的列表如下。
- POIFS (较差混淆技术实现文件系统) : 此组件是所有其他POI元件的基本因素。它被用来明确地读取不同的文件。
- HSSF (可怕的电子表格格式) : 它被用来读取和写入MS-Excel文件的xls格式。
- XSSF (XML格式) : 它是用于MS-Excel中XLSX文件格式。
- HPSF (可怕的属性设置格式) : 它用来提取MS-Office文件属性设置。
- HWPF (可怕的字处理器格式) : 它是用来读取和写入MS-Word的文档扩展名的文件。
- XWPF (XML字处理器格式) : 它是用来读取和写入MS-Word的docx扩展名的文件。
- HSLF (可怕的幻灯片版式格式) : 它是用于读取,创建和编辑PowerPoint演示文稿。
- HDGF (可怕的图表格式) : 它包含类和方法为MS-Visio的二进制文件。
- HPBF (可怕的出版商格式) : 它被用来读取和写入MS-Publisher文件。
创建 并 将数据写入 xls文件
//创建 excel 并写入数据到文件
@Test
public void test1() throws IOException {
String[] rowHeads = {"id", "name", "gender", "hobby", "birthday"};//定义第一行的数据
//1. 创建工作薄
HSSFWorkbook book = new HSSFWorkbook();
//2. 创建第一个 sheet【工作表】对象并设置sheet的名字
HSSFSheet sheet = book.createSheet("学生信息");
// sheet.getWorkbook().setSheetName(0,"学生信息"); //设置第一个工作表的名字
//3. 创建第一行,【从0开始】标题
HSSFRow row = sheet.createRow(0);
//4. 创建行的单元格
for (int i = 0; i < rowHeads.length; i++) {
//创建的单元格
HSSFCell cell = row.createCell(i);
//设置设置单元格内容
cell.setCellValue(rowHeads[i]);
}
//5. 创建写入数据
String[] data = new String[rowHeads.length];
List list = new ArrayList<>();
//创建student 数据
// public Student(Integer id, String name, Integer gender, String hobby, Date birthday)
for (int i = 0; i <= 10; i++) {
list.add(new Student(i + 1,
UUID.randomUUID().toString().substring(0, 4),
(int) (Math.random() * 2),
UUID.randomUUID().toString().substring(0, 4),
new Date()));
}
//数据写入到 【工作表 0】文件中
for (int i = 0; i < list.size(); i++) {
//创建行单元格设置参数【第一行已经有数据了】
HSSFRow row1 = sheet.createRow(i + 1);
Student temp = list.get(i);//获取写入的对象,准备写入数据
//设置单元格内容,重载
row1.createCell(0).setCellValue(temp.getId());
row1.createCell(1).setCellValue(temp.getName());
row1.createCell(2).setCellValue(temp.getGender());
row1.createCell(3).setCellValue(temp.getHobby());
//日期格式化
HSSFCellStyle style = book.createCellStyle(); //创建单元格样式
//设置 日期格式化的风格
style.setDataFormat(book.createDataFormat().getFormat("yyyy-MM-dd"));
//创建行的单元格
HSSFCell cell = row1.createCell(4);
cell.setCellStyle(style);//设置样式
cell.setCellValue(temp.getBirthday());//设置内容
//row1.createCell(4).setCellValue(temp.getBirthday()); //日期没有格式化
}
//6. 把 book写入到目的文件中
String path = "E:\\sample.xls";
book.write(new File(path));
book.close();
System.out.println("写入成功");
}
根据指定文件读取 xls文件并封装成 java对象
//读取 excel文件,把 excel中数据每行读成一个对象
//规则:工作表必须是类名,第一列必须是属性名
@Test
public void tese2() throws IOException, IllegalAccessException, InstantiationException, NoSuchFieldException {
File file = new File("E:\\sample.xls");//文件路径
String sheetName = "学生信息"; //工作表名
Class clazz = Student.class;//要保存的Java 对象名
//1. 创建工作薄:读取源文件
HSSFWorkbook book = new HSSFWorkbook(new FileInputStream(file));
//2. 根据工作表名获取一个工作表
HSSFSheet sheet = book.getSheet(sheetName);
//3. 获取第一行:列标题 对应的类的属性名
HSSFRow row = sheet.getRow(0);
//创建一个数组存储属性名
ArrayList fieldName = new ArrayList<>();
Iterator iterator = row.cellIterator();
while (iterator.hasNext()) {
Cell temp = iterator.next();
//存储第一行的信息,对象的成员变量
fieldName.add(temp.getStringCellValue());
}
// System.out.println(fieldName);//[id, name, sex, hubby, birthday]
//遍历其他行并封装对象
ArrayList |
读取 excel工具类
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.usermodel.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @ Auther: hwj
* @ Date: 2019/8/8 16:52
* @ Description: 读取excel工具类
*/
public class ExcelReaderUtil {
/**
* @methodName: readExcel 读取excel工具类
* @param: [is, tClass] 传入的实体类,成员变量类型只能是基本类型和字符串
* @return: java.util.List
* @auther: hwj
* @date: 2019/8/9 11:24
* @Description: 读取excel文件, 将其转换为javabean
*/
public static List readExcel2Bean(InputStream is, Class tClass)
throws IOException, IllegalAccessException, InstantiationException, ParseException {
List> list = ExcelReaderUtil.readExcel(is);
//-----------------------遍历数据到实体集合开始-----------------------------------
List listBean = new ArrayList();
Field[] fields = tClass.getDeclaredFields();
T uBean = null;
for (int i = 1; i < list.size(); i++) {// i=1是因为第一行不要
uBean = (T) tClass.newInstance();
List listStr = list.get(i);
for (int j = 0; j < listStr.size(); j++) {
if (j >= fields.length) {
break;
}
Field field = fields[j];
String datastring = listStr.get(j);
field.setAccessible(true);
if (datastring.length() > 0) {
Class<?> type = field.getType();
// 只支持8中基本类型和String类型 如有其他类型 请自行添加[添加日期]
if (type == String.class) {
field.set(uBean, datastring);
} else if (type == Integer.class || type == int.class) {
field.set(uBean, Integer.parseInt(datastring));
} else if (type == Double.class || type == double.class) {
field.set(uBean, Double.parseDouble(datastring));
} else if (type == Float.class || type == float.class) {
field.set(uBean, Float.parseFloat(datastring));
} else if (type == Long.class || type == long.class) {
field.set(uBean, Long.parseLong(datastring));
} else if (type == Boolean.class || type == boolean.class) {
field.set(uBean, Boolean.parseBoolean(datastring));
} else if (type == Short.class || type == short.class) {
field.set(uBean, Short.parseShort(datastring));
} else if (type == Byte.class || type == byte.class) {
field.set(uBean, Byte.parseByte(datastring));
} else if (type == Character.class || type == char.class) {
field.set(uBean, datastring.charAt(0));
} else if (type == Date.class) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
field.set(uBean, format.parse(datastring));
}
}
}
listBean.add(uBean);
}
return listBean;
}
/**
* Excel读取 操作,返回内容
*/
private static List> readExcel(InputStream is)
throws IOException {
Workbook wb = null;
try {
wb = WorkbookFactory.create(is);
} catch (IOException e) {
e.printStackTrace();
}
/** 得到第一个sheet */
assert wb != null;
Sheet sheet = wb.getSheetAt(0);
/** 得到Excel的行数 */
int totalRows = sheet.getPhysicalNumberOfRows();
/** 得到Excel的列数 */
int totalCells = 0;
if (totalRows >= 1 && sheet.getRow(0) != null) {
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
List> dataLst = new ArrayList>();
/** 循环Excel的行 */
for (int r = 0; r < totalRows; r++) {
Row row = sheet.getRow(r);
if (row == null)
continue;
List rowLst = new ArrayList();
/** 循环Excel的列 */
for (int c = 0; c < totalCells; c++) {
Cell cell = row.getCell(c);
String cellValue = "";
if (null != cell) {
HSSFDataFormatter hSSFDataFormatter = new HSSFDataFormatter();
cellValue = hSSFDataFormatter.formatCellValue(cell);
}
rowLst.add(cellValue);
}
/** 保存第r行的第c列 */
dataLst.add(rowLst);
}
return dataLst;
}
}
创建 excel工具类
import org.apache.poi.hssf.usermodel.*;
import java.io.File;
import java.lang.reflect.Field;
import java.util.*;
/**
* @author zhaokuii11@163.com
* @create 2021-11-16 22:11
* @Description 解析数据 编程 excel 文件
*/
public class ExcelCreateUtil {
/**
* 存储数据 map<类型,数据>
*/
private static Map, List<?>> MAP = new HashMap<>();
/**
* 添加数据
*
* @param clazz 类型
* @param list 数据
*/
public static void mapPut(Class<?> clazz, ArrayList<?> list) {
MAP.put(clazz, list);
}
/**
* @param path 路径+文件的名字
* @return 创建了几个 工作薄
* @throws Exception
*/
public static Integer createExcel(String path) throws Exception {
File file = new File(path);
if (!file.exists() && file.isDirectory()) {
file.mkdirs(); //如果文件不存在就创建
}
if (MAP.size() > 0) {
//创建工作薄
HSSFWorkbook workbook = new HSSFWorkbook();
Set> keySet = MAP.keySet();//所有的 字节码文件
keySet.forEach(key -> {
//System.out.println(key);
//创建第一个工作表:【下标0】
HSSFSheet sheet = workbook.createSheet(key.getSimpleName());
//创建行 一行一个对象 第一行是对象的属性名
HSSFRow heat = sheet.createRow(0);
Field[] fields = key.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//System.out.println(fields[i].getName());
heat.createCell(i).setCellValue(fields[i].getName());
}
final int[] count = {1};
MAP.get(key).forEach(instance -> { //instance 集合循环对象
//创建单元格 下标+1
HSSFRow row = sheet.createRow(count[0]);
//写入数据
Field[] fieldRow = key.getDeclaredFields();
for (int i = 0; i < fieldRow.length; i++) {
Field field = fieldRow[i];
field.setAccessible(true);
try {
Class<?> type = field.getType(); //类型
Object value = field.get(instance);//值
//只能设置 date double boolean string
//只设置了包装类
if (type == Integer.class || type == Byte.class || type == Short.class || type == Long.class || type == Float.class) {
//integer 不能转为 double 类型
row.createCell(i).setCellValue(Double.parseDouble(value.toString()));
} else if (type == String.class) {
row.createCell(i).setCellValue(value.toString());
} else if (type == Date.class) {
//日期类型封装
HSSFCellStyle style = workbook.createCellStyle();
style.setDataFormat(workbook.createDataFormat().getFormat("yyyy年MM月dd日"));
HSSFCell cell = row.createCell(i);
cell.setCellStyle(style);
cell.setCellValue((Date) value);
} else if (type == Boolean.class) {
row.createCell(i).setCellValue((Boolean) value);
} else {
//其他类型不进行判断直接 toString 返回
row.createCell(i).setCellValue(value.toString());
}
//row.createCell(i).setCellValue(value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
count[0]++;
});
});
workbook.write(file);
workbook.close();
return MAP.size();
}
return -1;
}
}