Excel 数据导入和导出工具使用手册
这篇文档将详细介绍如何使用 Excel 数据导入和导出工具来有效地处理 Excel 文件的导入和导出操作。这些工具包括三个主要类:ExcelExportUtil
、ExcelImportUtil
和 ExcelAttribute
。
ExcelAttribute - 定义 Excel 列属性
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAttribute {
/** 对应的列名称 */
String name() default "";
/** Excel 列的索引 */
int sort();
/** 字段类型对应的格式 */
String format() default "";
}
ExcelExportUtil - 导出数据
ExcelExportUtil 类
import com.mohr.domain.poi.ExcelAttribute;
import lombok.Getter;
import lombok.Setter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 导出 Excel 工具类
* 基于模板的方式导出:
*/
@Getter
@Setter
public class ExcelExportUtil {
private int rowIndex; // 写入数据的起始行
private int styleIndex; // 样式的行号
private Class clazz; // 对象的字节码
private Field fields[]; // 对象中的所有属性
public ExcelExportUtil(Class clazz, int rowIndex, int styleIndex) {
this.clazz = clazz;
this.rowIndex = rowIndex;
this.styleIndex = styleIndex;
fields = clazz.getDeclaredFields();
}
/**
* 基于注解导出
*
* @param response HTTP 响应对象
* @param is 模板的输入流
* @param objs 数据列表
* @param fileName 生成的文件名
* @throws Exception 可能的异常
*/
public void export(HttpServletResponse response, InputStream is, List objs, String fileName) throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook(is); // 创建工作簿
Sheet sheet = workbook.getSheetAt(0); // 读取工作表
CellStyle[] styles = getTemplateStyles(sheet.getRow(styleIndex)); // 提取样式
AtomicInteger datasAi = new AtomicInteger(rowIndex); // 行索引
for (T t : objs) {
Row row = sheet.createRow(datasAi.getAndIncrement()); // 创建行
for (int i = 0; i < styles.length; i++) {
Cell cell = row.createCell(i);
cell.setCellStyle(styles[i]);
for (Field field : fields) {
if (field.isAnnotationPresent(ExcelAttribute.class)) {
field.setAccessible(true);
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class);
if (i == ea.sort()) {
if (field.get(t) != null) {
cell.setCellValue(field.get(t).toString());
}
}
}
}
}
}
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1")));
response.setHeader("filename", fileName);
workbook.write(response.getOutputStream());
}
public CellStyle[] getTemplateStyles(Row row) {
CellStyle[] styles = new CellStyle[row.getLastCellNum()];
for (int i = 0; i < row.getLastCellNum(); i++) {
styles[i] = row.getCell(i).getCellStyle();
}
return styles;
}
}
步骤 1: 准备数据
- 准备需要导出的数据列表。
- 确保数据对象的属性与
ExcelAttribute
注解相匹配,包括列名、排序索引和格式。
步骤 2: 创建 Excel 模板文件
- 创建一个 Excel 模板文件,包含用于设置样式的行和用于填充数据的占位符单元格。
- 确保模板文件的格式与数据对象属性匹配。
步骤 3: 调用导出方法
// 示例代码
List results = userCompanyPersonalMapper.findByReport(companyId, month + "%");
InputStream fis = new FileInputStream("path/to/your/template.xlsx");
new ExcelExportUtil(EmployeeReportResult.class, 2, 2)
.export(response, fis, results, "员工报表.xlsx");
- 创建
ExcelExportUtil
对象,传入数据对象的类、数据起始行索引和样式行索引。 - 获取模板文件的输入流。
- 调用
export
方法,传入HttpServletResponse
对象、模板文件的输入流、数据列表和生成的文件名。
ExcelImportUtil - 导入数据
ExcelImportUtil 类
import com.mohr.domain.poi.ExcelAttribute;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class ExcelImportUtil {
private Class clazz;
private Field fields[];
public ExcelImportUtil(Class clazz) {
this.clazz = clazz;
fields = clazz.getDeclaredFields();
}
/**
* 从Excel文件中读取数据并映射到对象列表
*
* @param is Excel文件的输入流
* @param rowIndex 数据起始行索引
* @param cellIndex 数据起始列索引
* @return 包含映射数据的对象列表
*/
public List readExcel(InputStream is, int rowIndex, int cellIndex) {
List list = new ArrayList();
T entity = null;
try {
XSSFWorkbook workbook = new XSSFWorkbook(is);
Sheet sheet = workbook.getSheetAt(0);
// 计算行数(不包括标题行)
int rowLength = sheet.getLastRowNum();
for (int rowNum = rowIndex; rowNum