1. 前言
最近,处于工作的需要,老是需要跟excel打交道。找遍了各大论坛,没有找到一个趁手的工具,于是决定自己手写一个。和之前的easy-系列一样,开源出来供大家使用。
2. Maven引入
<dependency>
<groupId>io.github.xiaoyudeguang</groupId>
<artifactId>easy-pio</artifactId>
<version>4.0.2</version>
</dependency>
3. 代码实战
3.1 基础功能
package com.zlyx.easy.test.pio;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import com.zlyx.easy.core.collections.EasyList;
import com.zlyx.easy.pio.model.PioModel;
/**
*
* @Auth 赵光
* @Describle
* @2019年1月3日 下午2:54:41
*/
public class PioTest {
public static void main(String[] args) throws Exception {
// 创建一个PioModel对象来完成后续操作
PioModel pioModel = new PioModel("F:\\sheet\\test2.xlsx", 4, "测试测试");
// 设置表头
pioModel.setHeaders("姓名", "年龄", "身份证号", "手机号", "出生地", "现居地");
// 插入一行数据
pioModel.insertRow(EasyList.newList("小王", "18", "142330199501060326", "17696012456",
"北京市海淀区", "北京市海淀区"), 1);
// 插入一列数据
pioModel.insertColumn(EasyList.newList("11", "22", "33"), 1, 2);
// 自定义excel属性
Workbook book = pioModel.getWorkbook();
book.setActiveSheet(4);
// 自定义sheet表格属性
Sheet sheet = pioModel.getSheet();
sheet.setDefaultColumnWidth(15);
sheet.setDefaultRowHeight((short) 5);
// 写出excel
pioModel.write();
}
}
执行代码后,可以在系统文件夹下找到执行后的excel,效果图:
同时,控制台会展示数据预览图:
数据预览图的存在的意义就是,不需要生成excel表格就可以实时查看数据是不是自己想要的格式,可以说很方便了。如果调试期间不需要每次执行都生成excel,只需要 将
// 写出excel
pioModel.write();
替换为:
// 预览数据
pioModel.view();
就可以了。
3.2 高级功能
既然都有基础功能了,怎么能没有高级功能。来来来,先上代码为敬:
package com.zlyx.easy.test.pio;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.zlyx.easy.core.model.UserModel;
import com.zlyx.easy.core.tool.OptTool;
import com.zlyx.easy.core.utils.JsonUtils;
import com.zlyx.easy.pio.model.PioModel;
/**
*
* @Auth 赵光
* @Describle
* @2019年1月3日 下午2:54:41
*/
public class PioTest {
public static void main(String[] args) throws Exception {
UserModel model = new UserModel();
model.setId(OptTool.randomNum());
model.setName("小王");
model.setAge(10);
Map<String, String> data = JsonUtils.convert(model, Map.class);
writeExcel(data);
List<Map<String, String>> datas = Arrays.asList(data, data, data, data);
writeExcel(datas);
}
/**
* 写出单行数据
*
* @param data
* @throws Exception
*/
public static void writeExcel(Map<String, String> data) throws Exception {
PioModel pioModel = new PioModel("F:\\sheet\\test1.xlsx", "测试测试");
pioModel.setHeaders("姓名", "ID", "年龄");
pioModel.transer(data);
pioModel.write();
}
/**
* 写出多行数据
*
* @param datas
* @throws Exception
*/
public static void writeExcel(List<Map<String, String>> datas) throws Exception {
PioModel pioModel = new PioModel("F:\\sheet\\test2.xlsx", "测试测试");
pioModel.setHeaders("姓名", "ID", "年龄");
pioModel.transer(datas);
pioModel.write();
}
}
高级功能支持将map对象和List<Map>对象写出到excel。效果图就不上了哈,同上。
3.3 核心代码解读
咳咳,其实核心代码很简单,就两个类。注释已经很全了,这里把代码贴出来供各位大哥copy哈:
3.3.1 PioModel
package com.zlyx.easy.pio.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import com.zlyx.easy.core.buffer.EasyBuffer;
import com.zlyx.easy.core.tool.OptTool;
import com.zlyx.easy.pio.exception.PioException;
import com.zlyx.easy.pio.util.PioUtil;
/**
*
* @Auth 赵光
* @Describle
* @2019年1月3日 下午2:54:41
*/
public class PioModel {
/**
* 工作簿
*/
private Workbook workbook;
/**
* 表格
*/
private Sheet sheet;
/**
* 原始文件路径
*/
private String filePath;
/**
* 座标
*/
private int sheetAt;
private String title;
/**
* 表头
*/
private Collection<String> headers;
/**
*
* @param filePath 路径
* @throws Exception
*/
public PioModel(String filePath) throws Exception {
this(filePath, 0);
}
/**
*
* @param filePath 路径
* @param title 标题
* @throws Exception
*/
public PioModel(String filePath, String title) throws Exception {
this(filePath, 0, title);
}
/**
* @param filePath 路径
* @param sheetAt 座标
* @throws Exception
*/
public PioModel(String filePath, int sheetAt) throws Exception {
this(filePath, 0, null);
}
/**
*
* @param filePath 路径
* @param sheetAt 座标
* @param title 标题
* @throws Exception
*/
public PioModel(String filePath, int sheetAt, String title) throws Exception {
this.filePath = filePath;
this.sheetAt = sheetAt;
this.title = title;
this.workbook = PioUtil.getExcel(filePath);
this.sheet = PioUtil.getSheet(workbook, sheetAt, title);
}
/**
* 设置表头
*
* @param headers the headers to set
* @return
* @throws Exception
*/
public PioModel setHeaders(Collection<String> headers) throws Exception {
if (this.headers == null) {
insertRow(headers);
this.headers = headers;
}
return this;
}
/**
* 设置表头
*
* @param headers the headers to set
* @return
* @throws Exception
*/
public PioModel setHeaders(String... headers) throws Exception {
insertRow(Arrays.asList(headers));
this.headers = Arrays.asList(headers);
return this;
}
/**
* @return the workbook
*/
public Workbook getWorkbook() {
return workbook;
}
/**
* @return the sheet
*/
public Sheet getSheet() {
return sheet;
}
/**
* 写出到excel源文件
*
* @throws Exception
*
*/
public void write() throws Exception {
write(filePath);
}
/**
* 写出到指定excel文件
*
* @param filePath 写出路径
* @throws Exception
*/
public void write(String filePath) throws Exception {
System.out.println(view());
PioUtil.writeExcel(workbook, filePath);
}
/**
* 预览试图
*/
public String view() {
EasyBuffer eb = EasyBuffer.newBuffer();
Iterator<Row> rows = sheet.rowIterator();
Row row = null;
String cellValue = null;
while (rows.hasNext()) {
row = rows.next();
for (int cellnum = 0; cellnum < row.getLastCellNum(); cellnum++) {
cellValue = row.getCell(cellnum) == null ? "" : row.getCell(cellnum).getStringCellValue();
eb.append("|").append(OptTool.enough(cellValue + "", 10));
}
eb.append("|\n");
}
return eb.toString();
}
@Override
public String toString() {
return view();
}
/**
* 插入一行数据
*
* @param values 行数据
* @throws Exception
*/
public void insertRow(Collection<String> values) throws Exception {
insertRow(values, 0);
}
/**
* 插入一行数据
*
* @param values 行数据
* @param rowNum 插入行
* @throws Exception
*/
public void insertRow(Collection<String> values, int rowNum) throws Exception {
insertRow(values, rowNum, 0);
}
/**
* 插入一行数据
*
* @param values 行数据
* @param rowNum 插入行
* @param startNum 偏移量
* @throws Exception
*/
public void insertRow(Collection<String> values, int rowNum, int offset) throws Exception {
if (rowNum == 0 && headers != null && headers.size() > 0) {
PioException.throwException("因为您设置了表头,所以不允许给表头行插入数据!");
}
PioUtil.insertRow(workbook, sheetAt, title, new ArrayList<>(values), rowNum, offset);
}
/**
* 插入一行数据
*
* @param values 行数据
* @throws Exception
*/
public void insertColumn(Collection<String> values) throws Exception {
insertColumn(values, 0);
}
/**
* 插入一行数据
*
* @param values 行数据
* @param columnNum 插入行
* @throws Exception
*/
public void insertColumn(Collection<String> values, int columnNum) throws Exception {
insertColumn(values, 0, 0);
}
/**
* 插入一行数据
*
* @param values 行数据
* @param rowNum 插入行
* @param offset 偏移量
* @throws Exception
*/
public void insertColumn(Collection<String> values, int columnNum, int offset) throws Exception {
PioUtil.insertColumn(workbook, sheetAt, title, new ArrayList<>(values), columnNum, offset);
}
/**
* 将map对象转换为表格数据
*
* @param data
* @throws Exception
*/
public void transer(Map<String, String> data) throws Exception {
setHeaders(data.keySet());
insertRow(data.values(), 1);
}
/**
* 将集合数据转换为表格数据
*
* @param datas
* @throws Exception
*/
public void transer(List<Map<String, String>> datas) throws Exception {
if (datas == null || datas.isEmpty()) {
PioException.throwException("不支持转换空数据!");
}
setHeaders(datas.get(0).keySet());
for (int i = 0; i < datas.size(); i++) {
insertRow(datas.get(i).values(), i + 1);
}
}
}
3.3.2 PioUtil
package com.zlyx.easy.pio.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
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.util.StringUtils;
/**
* @Auth 赵光
* @Describle
* @2020年3月15日
*/
public class PioUtil {
/**
* 读取excel(存在则读取,没有则新建)
*
* @param filePath 读取路径
* @param sheetAt 表格座标
* @return
* @throws Exception
*/
public static Workbook getExcel(String filePath) throws Exception {
Workbook workbook = new XSSFWorkbook();
File file = new File(filePath);
if (file.exists()) {
InputStream fis = new FileInputStream(filePath);
if (filePath.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(fis);
} else if (filePath.endsWith(".xls") || filePath.endsWith(".et")) {
workbook = new HSSFWorkbook(fis);
}
fis.close();
}
return workbook;
}
/**
* 插入行数据
*
* @param workbook 工作簿
* @param sheetAt 表格座标
* @param title 表格标题
* @param values 值
* @param rowNum 插入行号
* @param offset 偏移量
* @return
* @throws Exception
*/
public static Workbook insertRow(Workbook workbook, int sheetAt, String title, List<Object> values, int rowNum,
int offset) throws Exception {
Sheet sheet = getSheet(workbook, sheetAt, title);
Row row = sheet.getRow(rowNum);
if (row == null) {
row = sheet.createRow(rowNum);
}
for (int i = 0; i < values.size(); i++) {
Cell cell = row.getCell(i + offset);
if (cell == null) {
cell = row.createCell(i + offset);
}
cell.setCellValue(String.valueOf(values.get(i)));
}
return workbook;
}
/**
* 插入列数据
*
* @param workbook 工作簿
* @param sheetAt 表格座标
* @param title 表格标题
* @param values 值
* @param columnNum 插入列号
* @param offset 偏移量
* @return
* @throws Exception
*/
public static Workbook insertColumn(Workbook workbook, int sheetAt, String title, List<Object> values,
int columnNum, int offset) throws Exception {
Sheet sheet = getSheet(workbook, sheetAt, title);
for (int i = 0; i < values.size(); i++) {
Row row = sheet.getRow(i + offset);
if (row == null) {
row = sheet.createRow(i + offset);
}
Cell cell = row.getCell(columnNum);
if (cell == null) {
cell = row.createCell(columnNum);
}
cell.setCellValue(String.valueOf(values.get(i)));
}
return workbook;
}
/**
* 解析sheet
*
* @param workbook 工作簿
* @param sheetAt 座标
* @param title 标题
* @return
*/
public static Sheet getSheet(Workbook workbook, int sheetAt, String title) {
int size = sheetAt - workbook.getNumberOfSheets();
if (size >= 0) {
for (int i = 0; i <= size; i++) {
if (i == size && !StringUtils.isEmpty(title)) {
workbook.createSheet(title);
} else {
workbook.createSheet();
}
}
}
return workbook.getSheetAt(sheetAt);
}
/**
* 写出excel
*
* @param workbook 工作簿
* @param filePath 写出路径
* @throws Exception
*/
public static void writeExcel(Workbook workbook, String filePath) throws Exception {
File file = new File(filePath);
File parrnetFile = file.getParentFile();
if (!parrnetFile.exists()) {
parrnetFile.mkdirs();
}
FileOutputStream os = new FileOutputStream(filePath);
workbook.write(os);
os.flush();
os.close();
System.out.println("写出excel完成!");
}
}
完事,收工