Java Excel 文件导出导入


特点:

支持xls、xlsx格式;

导出时支持自定义表格标题和表格数据,支持一个文档里多个Sheet;

 

依赖:

Java Excel 文件导出导入

        <!--excel util-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>

maven

代码:

Java Excel 文件导出导入

/** 工具类,用于将数据导出到excel文件(可以导出到一个文件的多个Sheet) 或 从excel文件读取数据 */
@Slf4j
public class ExcelUtil {
public static void main(String[] args) throws IOException {
String fileName = "test.xls";
exportExcel(
Arrays.asList(
new SheetInfo<StuExpDownloadVO>(
"class1", ("用户名, 姓名, 完成情况, 得分, 评语").split(","),
Arrays.asList(new StuExpDownloadVO("zhangsna", "张三", "未开始", 22.0, "good"), new StuExpDownloadVO("lisi", "李四", "进行中", 21.0, "bad"))
),
new SheetInfo<StuExpDownloadVO>(
"class2", ("用户名, 姓名, 完成情况").split(","), Arrays.asList(new StuExpDownloadVO("wangwu", "王五", "已完成", 20.0, "good"), new StuExpDownloadVO("zhaoliu", "赵六", "未开始", 19.0, "bad"))
)
), Files.newOutputStream(Paths.get("a.xls")));
exportExcel(
("用户名, 姓名, 完成情况, 得分, 评语").split(","),
Arrays.asList(new StuExpDownloadVO("zhangsna", "张三", "未开始", 22.0, "good"), new StuExpDownloadVO("lisi", "李四", "进行中", 21.0, "bad")),
Files.newOutputStream(Paths.get("b.xls")));
}
private ExcelUtil() {
}
private static final String datetimeFormat = "yyyy-MM-dd HH:mm:ss";
/**
* @see {@link #exportExcel(String[] headers, Collection dataset, OutputStream out, String datetimeFormat) }
*/
public static <T> void exportExcel(String[] headers, Collection<T> dataSet, OutputStream out) {
exportExcel(headers, dataSet, out, datetimeFormat);
}
/**
* 利用JAVA的反射机制,将放置在JAVA集合中并且符合一定条件的数据以EXCEL的形式输出到指定输出流。<br>
* <br>
* <b>输出后会关闭输出流</b>
*
* @param headers        表格属性列名数组。注意:数组中列名的顺序须与待导出的javabean属性的定义顺序一致
* @param dataset        需要显示的数据集合,集合中java bean对象的所有非继承属性的值均会被输出。此方法支持的
*                       javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
* @param out            与输出设备关联的流对象,可以将 EXCEL 文档导出到本地文件或者网络中
* @param datetimeFormat 如果有时间数据,设定输出格式。
*/
public static <T> void exportExcel(String[] headers, Collection<T> dataset, OutputStream out, String datetimeFormat) {
exportExcel(Arrays.asList(new SheetInfo("sheet 0", headers, dataset)), out, datetimeFormat);
}
public static <T> void exportExcel(List<SheetInfo<T>> sheetInfos, OutputStream out) {
exportExcel(sheetInfos, out, datetimeFormat);
}
/**
* 利用JAVA的反射机制,将放置在JAVA集合中并且符合一定条件的数据以EXCEL的形式输出到指定输出流。<br>
* <br>
* <b>输出后会关闭输出流</b>
*
* @param sheetInfos         EXCEL 文档中的Sheet信息定义
* @param out            与输出设备关联的流对象,可以将 EXCEL 文档导出到本地文件或者网络中
* @param datetimeFormat 如果有时间数据,设定输出格式。
*/
public static <T> void exportExcel(List<SheetInfo<T>> sheetInfos, OutputStream out, String datetimeFormat) {
sheetInfos = Optional.ofNullable(sheetInfos).orElse(Collections.emptyList());
// 生成Excel文档
Workbook workbook = generateWorkbook();
// 生成表头样式
CellStyle tableHeaderStyle = generateTableHeaderStyle(workbook);
// 生成表体样式
CellStyle tableBodyStyle = generateTableBodyStyle(workbook);
// 时间值格式化工具
DateTimeFormatter sdf = DateTimeFormatter.ofPattern(datetimeFormat);
// 生成Excel文档中的sheet
for (int siIndex = 0; siIndex < sheetInfos.size(); siIndex++) {
SheetInfo sheetInfo = sheetInfos.get(siIndex);
String[] headers = sheetInfo.getHeaders();
//创建sheet
Sheet sheet = workbook.createSheet();
workbook.setSheetName(siIndex, sheetInfo.getName());
sheet.setDefaultColumnWidth(18);
// 声明一个绘制图片的顶级管理器
Drawing patriarch = sheet.createDrawingPatriarch();
// 定义注释的大小和位置
// HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
// 0, 0, 0, (short) 4, 2, (short) 6, 5));
// 设置注释内容
// comment.setString(new HSSFRichTextString("可以在POI中添加注释!"));
// 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
// comment.setAuthor("sensetime");
// 填充表格标题行
int rowIndex = 0;
Row row = sheet.createRow(rowIndex);
for (int i = 0; i < headers.length; i++) {
Cell cell = row.createCell(i);
cell.setCellStyle(tableHeaderStyle);
cell.setCellValue(generateRichTextString(headers[i]));
}
rowIndex++;
// 填充表格数据行
Iterator<T> rowDataIt = sheetInfo.getDataset().iterator();
Field[] fields = null;
while (rowDataIt.hasNext()) {
row = sheet.createRow(rowIndex);
T t = (T) rowDataIt.next();
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
if (null == fields) {
fields = t.getClass().getDeclaredFields();
}
for (int i = 0; i < fields.length && i < headers.length; i++) {
//HSSFCell cell = row.createCell(i);
Cell cell = row.createCell(i);
cell.setCellStyle(tableBodyStyle);
Field field = fields[i];
field.setAccessible(true);
try {
Object value = field.get(t);
// 判断值的类型后进行强制类型转换
String textValue = null;
// if (value instanceof Integer) {
// int intValue = (Integer) value;
// cell.setCellValue(intValue);
// } else if (value instanceof Float) {
// float fValue = (Float) value;
// textValue = new HSSFRichTextString(
// String.valueOf(fValue));
// cell.setCellValue(textValue);
// } else if (value instanceof Double) {
// double dValue = (Double) value;
// textValue = new HSSFRichTextString(
// String.valueOf(dValue));
// cell.setCellValue(textValue);
// } else if (value instanceof Long) {
// long longValue = (Long) value;
// cell.setCellValue(longValue);
// }
if (value == null) {
textValue = "";
} else if (value instanceof Date) {
Date date = (Date) value;
textValue = sdf.format(date.toInstant());
} else if (value instanceof byte[]) {
// 有图片时,设置行高为60px;
row.setHeightInPoints(60);
// 设置图片所在列宽度为80px,注意这里单位的一个换算
sheet.setColumnWidth(i, (short) (35.7 * 80));
sheet.autoSizeColumn(i);
byte[] bsValue = (byte[]) value;
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, rowIndex, (short) 6, rowIndex);
anchor.setAnchorType(ClientAnchor.AnchorType.byId(2));
patriarch.createPicture(anchor, workbook.addPicture(bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
} else {
// 其它数据类型都当作字符串简单处理
textValue = value.toString();
}
// 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
if (textValue != null) {
Pattern p = Pattern.compile("^//d+(//.//d+)?$");
Matcher matcher = p.matcher(textValue);
if (matcher.matches()) {
// 是数字则当作double处理
cell.setCellValue(Double.parseDouble(textValue));
} else {
cell.setCellValue(generateRichTextString(textValue));
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
rowIndex++;
}
}
try {
workbook.write(out);
} catch (IOException e) {
log.error(e.getMessage(), e);
} finally {// 清理资源
if (null != workbook) {
try {
workbook.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
/**
* 读取excel文件内容,存入到字节流。每行结尾加了换行符,一行中各字段后跟一逗号来分隔
*/
public static ByteArrayInputStream importExcel(InputStream in, int sheetIndex) throws InvalidFormatException, IOException, InstantiationException, IllegalAccessException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (Workbook workbook = generateWorkbookFromInputStream(in)) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
for (int ri = sheet.getFirstRowNum(); ri <= sheet.getLastRowNum(); ri++) {
Row row = sheet.getRow(ri);
for (int ci = row.getFirstCellNum(); ci < row.getLastCellNum(); ci++) {
Cell cell = row.getCell(ci);
String value = getValue(cell) + ", ";
baos.write(value.getBytes());
// System.out.printf("%s ", value);
}
baos.write("/n".getBytes());
// System.out.println("");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
;
return new ByteArrayInputStream(baos.toByteArray());
}
private static String getValue(Cell cell) {
if (cell.getCellType() == CellType.BOOLEAN) {
// 返回布尔类型的值
return String.valueOf(cell.getBooleanCellValue());
} else if (cell.getCellType() == CellType.NUMERIC) {
// 返回数值类型的值
return String.valueOf(cell.getNumericCellValue());
} else {
// 返回字符串类型的值
return String.valueOf(cell.getStringCellValue());
}
}
/**
* excepl 文档中的一个Sheet的信息定义
*/
@Data
@AllArgsConstructor
public static class SheetInfo<T> {
private String name;//表格名称
private String[] headers;//表格列名
private Collection<T> dataset;//表格数据,每个元素代表一行
}
//以下为为了同时兼容 xls、xlsx 格式的excel文档而定义的方法
/**
* 是否生成xlsx文档,为true则生成xlsx格式的文档(Excel2007及以后的版本,扩展名是.xlsx)、否则生成xls格式的文档(Excel2003及以前的版本,扩展名是.xls)。
*/
private static final boolean USE_XLSX = true;
private static RichTextString generateRichTextString(String val) {
RichTextString res = USE_XLSX ? new XSSFRichTextString(val) : new HSSFRichTextString(val);
//res.applyFont(new xx);
return res;
}
/**
* 创建一个excel文档
*/
private static Workbook generateWorkbook() {
//HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
//XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
Workbook res = USE_XLSX ? new XSSFWorkbook() : new HSSFWorkbook();
return res;
}
/**
* 创建一个excel文档
*/
private static Workbook generateWorkbookFromInputStream(InputStream in) throws IOException {
//HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
//XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
Workbook res = USE_XLSX ? new XSSFWorkbook(in) : new HSSFWorkbook(in);
return res;
}
private static CellStyle generateTableHeaderStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
Font font = workbook.createFont();
font.setColor(IndexedColors.WHITE.getIndex());
font.setFontHeightInPoints((short) 12);
//font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style.setFont(font);
return style;
}
private static CellStyle generateTableBodyStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
style.setFillForegroundColor(IndexedColors.WHITE.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
Font font = workbook.createFont();
font.setColor(IndexedColors.GREY_80_PERCENT.index);
//font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
style.setFont(font);
return style;
}
}

ExcelUtil

 

原创文章,作者:bd101bd101,如若转载,请注明出处:https://blog.ytso.com/274577.html

(0)
上一篇 2022年7月15日
下一篇 2022年7月15日

相关推荐

发表回复

登录后才能评论