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完成!");
}
}
完事,收工