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

}

完事,收工

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