Excel工具类

一、开发原因

最近工作的时候,正在写关于Excel导出功能,由于当前使用的工具类不太灵活和不易看懂,自己从头写又很浪费时间等原因,我决定自己写一款很简单的Excel导出的工具类,仅仅是出于学习的目的。

二、工具类的使用

基于HSSFWorkbook,介绍如下:
首先需要一个Maven依赖:

        <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.0.0</version></dependency>

工具类的名称是ExcelUtil,类中包含两个主要的方法可以来调用:

本方法有两个形参,分别是String fileName(文件名), List<List> dataList(数据列表)

具体使用方法如下:
首先创建一个数据列表,一般都是从数据库获取,这里我手动创建一个:

public static List<List<Object>> listData() {List<List<Object>> dataList = new ArrayList<>();  //所需要的数据列表的类型String[] thStrings = {"id", "名字", "性别", "年龄", "籍贯", "学历"};//表头数据ArrayList<Object> th = new ArrayList<>(Arrays.asList(thStrings));dataList.add(th);   // 将表头数据放入数据列表中//表格数据ArrayList<Object> data = new ArrayList<>();data.add("001");data.add("iKun");data.add("man");data.add(18);data.add("美国");data.add("rap博士");for (int i = 0; i < 200; i++) {dataList.add(data);  // 循环将200个iKun放入数据列表中}return dataList;}

在main中使用:

    public static void main(String[] args) {String title = "Excel";   // 文件名List<List<Object>> listData = listData(); // 数据列表ExcelUtil excelUtil = new ExcelUtil();Boolean result = excelUtil.exportExcelList(title, listData);System.out.println("result = " + result);}

导出成功后会返回一个:

导出的文件如下:

第二个方法是基于类的的反射和注解,主要是导出对应的实体类对象列表数据

exportExcelClass形参是三个,分别是String fileName(导出Excel的文件名), Class<?>
aClass(导出对应实体类类的反射), List dataList(对象集合的数据列表)

本方法是基于类的反射和注解实现的,首先在需要导出的实体类中的属性上方添加一注解,如下:

此注解有两个参数:value(表头)order(表格的列顺序,从小到大,从左向右排列,默认值为0)

将注解写在实体类的属性上以后,还是首先创建一个数据列表:

 private static List<Student> studentListData() {List<Student> studentList = new ArrayList<>();Student iKun = new Student(18, "KunKun", 2.5, new Date());for (int i = 0; i < 10; i++) {studentList.add(iKun);}return studentList;}

在main中使用:

 public static void main(String[] args) {String title = "iKun花名册";   // 文件名List<Student> studentList = studentListData();  //数据列表ExcelUtil<Student> excelUtil = new ExcelUtil<>();Boolean aBoolean = excelUtil.exportExcelClass(title, Student.class, studentList);System.out.println("aBoolean = " + aBoolean);}

最终导出的结果:

上述就是工具类的使用。

三、工具类的介绍

类有以下几个属性和方法:

其中 wb; getWb() getSheet() outputFile() 不必过于关注。

主要是剩余方法:
setCellStyle(设置单元格的样式)
exportExcelClass(根据实体类导出数据)
exportExcelList(根据list列表导出数据)
其中exportExcelClass调用了exportExcelList,exportExcelList调用了setCellStyle

1、表头样式

2、数据样式

数据分为文本数据和数字数据,可根据需要修改

3、标题样式

四、源码

注解接口类:

import java.lang.annotation.*;@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface ExportExcel {String value() default "";  //表头int order() default 0;  // 顺序
}

工具实现类:

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;/*** 一个Excel文件对应于一个workbook(HSSFWorkbook),* 一个workbook可以有多个sheet(HSSFSheet)组成,* 一个sheet是由多个row(HSSFRow)组成,* 一个row是由多个cell(HSSFCell)组成。*/
public class ExcelUtil<T> {private final HSSFWorkbook wb = new HSSFWorkbook();public HSSFWorkbook getWb() {return wb;}/*** 获取HSSFSheet,内部方法不必关注** @param fileName 文件名* @param wb       HSSFWorkbook* @return HSSFSheet*/private static HSSFSheet getSheet(String fileName, HSSFWorkbook wb) {return wb.createSheet(fileName);}/*** 通过类的反射导出 Excel** @param fileName 文件名* @param aClass   类对象* @param dataList 数据列表* @return 是否成功*/public Boolean exportExcelClass(String fileName, Class<?> aClass, List<T> dataList) {List<Object> thRow = new ArrayList<>();  //表头数据List<List<Object>> thOrderList = new ArrayList<>();       //存放数据和顺序for (Field declaredField : aClass.getDeclaredFields()) {  //循环遍历对象的属性列表if (declaredField.isAnnotationPresent(ExportExcel.class)) {  //找到被注解的属性List<Object> orderValues = new ArrayList<>();int order = declaredField.getAnnotation(ExportExcel.class).order();  //获取属性的orderString value = declaredField.getAnnotation(ExportExcel.class).value();//取出属性注解的value值orderValues.add(order);orderValues.add(value);thOrderList.add(orderValues);}thOrderList.sort(Comparator.comparingInt(a -> (Integer) a.get(0)));  //排序}for (List<Object> objects : thOrderList) {thRow.add(objects.get(1));}List<List<Object>> lists = new ArrayList<>(); //表格数据lists.add(thRow);  //将表头数据加入for (T t : dataList) {  //循环遍历对象列表Field[] declaredFields = t.getClass().getDeclaredFields();  //反射得到对象的属性列表List<List<Object>> orderList = new ArrayList<>();       //存放数据和顺序for (Field declaredField : declaredFields) {    //循环遍历对象的属性if (declaredField.isAnnotationPresent(ExportExcel.class)) {int order = declaredField.getAnnotation(ExportExcel.class).order();  //获取属性的orderString name = declaredField.getName();  //获取属性的nameString getValueMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);  // 获取属性的get方法Method method = null;try {method = t.getClass().getMethod(getValueMethodName);Object invoke = method.invoke(t);if (invoke == null) {invoke = "";}List<Object> list = new ArrayList<>();list.add(order);list.add(invoke);orderList.add(list);} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {throw new RuntimeException(e);}}}orderList.sort(Comparator.comparingInt(a -> (Integer) a.get(0))); //排序ArrayList<Object> rowList = new ArrayList<>();for (List<Object> orderData : orderList) {rowList.add(orderData.get(1));}lists.add(rowList);}return exportExcelList(fileName, lists);}/*** 通过list数据集合导出** @param fileName 文件名* @param dataList 数据列表(list)* @return 导出是否成功*/public Boolean exportExcelList(String fileName, List<List<Object>> dataList) {HSSFSheet sheet = getSheet(fileName, wb);int thSize = dataList.get(0).size() - 1; //表头数据列表长度//标题内容  col列 row行CellStyle titleStyle = setCellStyle("Arial", 16, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);//设置title单元格样式HSSFRow titleRow = sheet.createRow(0);HSSFCell titleCell = titleRow.createCell(0);titleCell.setCellValue(fileName);/*合并单元格第一个参数:第一个单元格的行数(从0开始)第二个参数:第二个单元格的行数(从0开始)第三个参数:第一个单元格的列数(从0开始)第四个参数:第二个单元格的列数(从0开始)*/CellRangeAddress range = new CellRangeAddress(0, 0, 0, thSize);sheet.addMergedRegion(range);titleCell.setCellStyle(titleStyle);//设置列的宽度int size = dataList.get(0).size();int[] colSize = new int[size];for (List<Object> data : dataList) {for (int i = 0; i < data.size(); i++) {int length = data.get(i).toString().length();if (colSize[i] < length) {colSize[i] = length;   //获取每一列中最长的数据}}}for (int i = 0; i < colSize.length; i++) {sheet.setColumnWidth(i, 2000 + colSize[i] * 200);   ///设置列的宽度}//表头行数int rowId = 1;//数据CellStyle style = setCellStyle("Arial", 12, false, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);CellStyle numStyle = setCellStyle("Arial", 12, false, HorizontalAlignment.LEFT, VerticalAlignment.CENTER);for (List<Object> strings : dataList) {HSSFRow row = sheet.createRow(rowId);for (int i = 0; i < strings.size(); i++) {HSSFCell cell = row.createCell(i);//表头的样式if (rowId == 1) {CellStyle thStyle = setCellStyle("Arial", 12, false, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);thStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());thStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);cell.setCellStyle(thStyle);}//数据的样式if (rowId != 1) {if (strings.get(i) instanceof Double|| strings.get(i) instanceof Float|| strings.get(i) instanceof Long|| strings.get(i) instanceof Integer) {cell.setCellStyle(numStyle);} else {cell.setCellStyle(style);}}//数据类型处理if (strings.get(i) instanceof Double) {cell.setCellValue((double) strings.get(i));} else if (strings.get(i) instanceof Float) {cell.setCellValue((double) (Float) strings.get(i));} else if (strings.get(i) instanceof Long) {cell.setCellValue((double) (Long) strings.get(i));} else if (strings.get(i) instanceof Integer) {cell.setCellValue((double) (Integer) strings.get(i));} else if (strings.get(i) instanceof Date) {DataFormat format = wb.createDataFormat();style.setDataFormat(format.getFormat("yyyy-MM-dd"));cell.setCellValue((Date) strings.get(i));} else if (strings.get(i) instanceof String) {cell.setCellValue((String) strings.get(i));} else {try {cell.setCellValue((String) Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), "fieldtype." + strings.get(i).getClass().getSimpleName() + "Type")).getMethod("setValue", Object.class).invoke((Object) null, strings.get(i)));} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException |ClassNotFoundException e) {throw new RuntimeException(e);}}}rowId++;}//输出Excelreturn outputFile(fileName);}/*** 设置单元格字体样式** @param fontType        字体类型* @param fontSize        字体大小* @param bold            字体是否加粗* @param textAlign_l_a_r 字体对齐方式(左右)* @param textAlign_t_a_b 字体对齐方式(上下)* @return CellStyle*/public CellStyle setCellStyle(String fontType, int fontSize, boolean bold, HorizontalAlignment textAlign_l_a_r, VerticalAlignment textAlign_t_a_b) {HSSFCellStyle cellStyle = wb.createCellStyle();if (textAlign_l_a_r != null) {cellStyle.setAlignment(textAlign_l_a_r);//设置对齐方式}if (textAlign_t_a_b != null) {cellStyle.setVerticalAlignment(textAlign_t_a_b); //设置对齐方式}HSSFFont font = wb.createFont();font.setFontName(fontType);font.setFontHeightInPoints((short) fontSize);font.setBold(bold);cellStyle.setFont(font);// 设置字体return cellStyle;}/*** 文件输出流** @param fileName 文件名* @return 返回是否成功*/private Boolean outputFile(String fileName) {FileOutputStream output = null;try {output = new FileOutputStream("D://" + fileName + ".xls");wb.write(output);output.flush();output.close();return true;} catch (IOException e) {throw new RuntimeException(e);}}}

后面还会对这个类进行持续的修改优化!!!!,希望可以给各位有一定的帮助!!欢迎讨论分享

java Excel导出工具类相关推荐

  1. 自己写的java excel导出工具类

    最近项目要用到excel导出功能,之前也写过类似的代码.因为这次项目中多次用到excel导出.这次长了记性整理了一下 分享给大伙 欢迎一起讨论 生成excel的主工具类: public class E ...

  2. Excel导出工具类

    前言 相信不少同学在开发中都会遇到导出excel这种需求,今天将Excel的导出工具和大家进行一个分享,如有错误还请大佬们批评指正.该工具类可以实现自定义列宽,自定义表头样式,实现了多sheet页合并 ...

  3. Java之Excel导出工具类使用教程

    前言: 本工具类经过PostMan和web页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具. 市面上有很多封装好的导出工具(如:阿里的eas ...

  4. Poi excel 导出 工具类参考

    public void poiCreateExcel(HttpServletResponse response, Map<String, Object> map) {// 下载文件信息St ...

  5. esayExcel导出工具类

    依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artif ...

  6. javaExcel 导出(基于POI的复杂表格导出工具类)

    我的需求: 项目中有一些工程表格需要导出,设计到行列合并,定制样式,原有工具类冗余,内聚性强.所以想写一个可以随意定制excel的工具类,工具类满足需求: 对于常用的工程表格有模板格式,可以任意插拔. ...

  7. java Excel导入导出工具类 及使用demo

    java Excel导入导出工具类 及使用demo 前言:相信进来的都是想尽快解决问题的,话不多说,按照以下步骤来,可以操作导出excel到本地,导入同理,自行学习.步骤一:直接复制以下excel工具 ...

  8. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

  9. Java Excel导出复杂excel表格样式之ExcelUtil工具类

    Java Excel导出包括普通导出及复杂表格样式,主要是对于需要进行行列合并的列进行特殊处理,计算清楚起始行,结束行,起始列,结束列. 普通导出可以是所有列,也可以是包含某些列,或者排除某些列: 1 ...

最新文章

  1. Mysql在大型网站的应用架构演变
  2. [安全攻防进阶篇] 六.逆向分析之OllyDbg逆向CrackMe01-02及加壳判断
  3. [C/C++基础知识] 那些被遗忘的链表知识
  4. Manthan, Codefest 16
  5. 秦九韶算法matlab实验报告,数值分析上机实验报告.doc
  6. ansible 配置文件
  7. 布局网页表格要求其列平均分布的简单操作
  8. maven 打包失败 提示找不到jar的问题
  9. 将自己的dcm数据制作成LUNA16数据集提供数据样式。
  10. linux 添加隐藏wi-fi,隐藏wifi怎么设置?
  11. [原]Java程序员的JavaScript学习笔记(1——理念)
  12. java.net.bindexception: address already in use: jvm_bind:8080
  13. MiniProfiler使用点滴记录-2017年6月23日11:08:23
  14. Idea中的搜索快捷键
  15. 《武义九州》隐私政策
  16. 第八章 机器人语音交互 课后作业
  17. 运算符优先级及记忆口诀
  18. SparkSQL的入门实践教程
  19. 软件测试前置基础知识(基本概念,DOS命令)
  20. 两台电脑不在一个城市,如何使这两台电脑构成一个局域网?

热门文章

  1. 程序执行报错Missing Connection or ConnectionString 解决方法
  2. iOS微信聊天记录迁移时报错:当前网络状况复杂
  3. rabbitmq默认guest登录问题
  4. 【教你赚钱】5分钟成为副业致富的独立开发者
  5. Unity3D显示Kinect线条图
  6. 2021中国IC封装基板市场现状及未来发展趋势
  7. 初中计算机科学生情况,初中计算机科学与技术的现代化运用探究
  8. 计算机的云是什么意思_网络上所说的云是什么意思?能通俗一点解释吗?
  9. 用H5 canvas实现唯美渐变色块的绘制
  10. 解决jrebe-JVMTI[FATAL] Couldnt write to C:\Users\启动报错