easy-pio

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完成!");
	}

}

完事,收工

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章