灵活的 反射 多sheet选项卡 导入导出 Excel 工具类

11 篇文章 0 订阅

 

 
<!--excel导入导出start-->
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.8</version>
</dependency>
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>3.8</version>
</dependency>
<!--excel导入导出end-->

在pom.xml中引入导入导出Jar包。

 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * excel导入导出注解类
 * Created by zxy on 2017/11/1.
 */
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {
    //导入导出字段在excel中的名字
    String title();
}

ExcelField注释类

 

import org.springframework.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyUtils {

    //获取格式化的时间,参数都为空则返回当前时间
    public static final String getFormatDate(String style, Date date) {
        return new SimpleDateFormat(isEmpty(style) ? "yyyy-MM-dd" : style).format(date == null ? new Date() : date);
    }

    //判断为null或空字符串
    public static final boolean isEmpty(String s) {
        return StringUtils.isEmpty(s);
    }

    //URL 编码, Encode默认为UTF-8.
    public static final String urlEncode(String s) throws UnsupportedEncodingException {
        return URLEncoder.encode(s, "UTF-8");
    }
}

MyUtils工具类

 

import com.zxy.whbackstage.common.MyUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 * @Description: excel导出封装类
 * @author zxy
 * @date 2017年11月1日
 */
public class ExcelUtil
{
    //通用
    public static <Q> void writeExcel(HttpServletResponse response, String fileName, List<Q> list, Class<Q> cls) throws IOException, IllegalArgumentException, IllegalAccessException
    {
        HSSFWorkbook wb = new HSSFWorkbook();

        Field[] fields = cls.getDeclaredFields();
        ArrayList<String> headList = new ArrayList<String>();

        for (Field f : fields)
        {
            ExcelField field = f.getAnnotation(ExcelField.class);
            if (field != null)
            {
                headList.add(field.title());
            }
        }

        CellStyle style = getCellStyle(wb);
        List<List<Q>> listTemp = new ArrayList<>();
        if(list!=null){
            int total = list.size();
            int cycelTotal = total / 65000;
            int tt = 0;
            for (int i = 0; i <= cycelTotal; i++) {
                if(((i+1)*65000)>total){
                    tt = total;
                }else{
                    tt = ((i+1)*65000);
                }
                listTemp.add(list.subList(i*65000,tt));
            }
        }
        for (int k = 0; k < listTemp.size(); k++) {
            Sheet sheet = wb.createSheet();
            /**
             * 设置Excel表的第一行即表头
             */
            Row row = sheet.createRow(0);
            for (int i = 0; i < headList.size(); i++)
            {
                Cell headCell = row.createCell(i);
                headCell.setCellType(Cell.CELL_TYPE_STRING);
                headCell.setCellStyle(style);//设置表头样式
                headCell.setCellValue(String.valueOf(headList.get(i)));
                sheet.autoSizeColumn((short) i);// 设置单元格自适应
                //sheet.setColumnWidth(0, 15 * 256);
            }
            if(listTemp.get(k)!=null){
                for (int i = 0; i < listTemp.get(k).size(); i++)
                {
                    Row rowdata = sheet.createRow(i + 1);//创建数据行
                    Q q = listTemp.get(k).get(i);
                    Field[] ff = q.getClass().getDeclaredFields();
                    int j = 0;
                    for (Field f : ff)
                    {
                        ExcelField field = f.getAnnotation(ExcelField.class);
                        if (field == null)
                        {
                            continue;
                        }
                        f.setAccessible(true);
                        Object obj = f.get(q);
                        Cell cell = rowdata.createCell(j);
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        // 当数字时
                        if (obj instanceof Integer) cell.setCellValue((Integer) obj);
                        // 当长整形
                        if (obj instanceof Long) cell.setCellValue((Long) obj);
                        // 当为字符串时
                        if (obj instanceof String) cell.setCellValue((String) obj);
                        // 当为布尔时
                        if (obj instanceof Boolean) cell.setCellValue((Boolean) obj);
                        // 当为时间时
                        if (obj instanceof Date) cell.setCellValue(MyUtils.getFormatDate("yyyy-MM-dd", (Date) obj));
                        // 当为时间时
                        if (obj instanceof Calendar) cell.setCellValue((Calendar) obj);
                        // 当为小数时
                        if (obj instanceof Double) cell.setCellValue((Double) obj);
                        //将序号替换为123456
                        if (j == 0) cell.setCellValue(i + 1);
                        j++;
                    }
                }
            }

        }
        response.setContentType( "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=report.zip");
        OutputStream ouputStream = null;
        try
        {
            ouputStream = response.getOutputStream();
            ZipOutputStream zip = new ZipOutputStream(ouputStream);
            ZipEntry entry = new ZipEntry(MyUtils.urlEncode(fileName));
            zip.putNextEntry(entry);
            wb.write(zip);
            zip.flush();
            zip.close();
        }
        finally
        {
            ouputStream.flush();
            ouputStream.close();
        }
    }

    /**
     *
     * @Description:设置表头样式
     * @author zxy
     * @date 2017年11月1日
     */
    public static CellStyle getCellStyle(Workbook wb)
    {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 12);//设置字体大小
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//加粗
        style.setFillForegroundColor(HSSFColor.LIME.index);// 设置背景色
        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        style.setAlignment(HSSFCellStyle.SOLID_FOREGROUND);//让单元格居中
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
        style.setWrapText(true);//设置自动换行
        style.setFont(font);
        return style;
    }

}

excel导出封装类

 

 
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;

import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @Description: excel导入封装类
 * @author zxy
 * @date 2017年11月28日
 */
@Slf4j
public class ReadExcelUtil {

    public static <Q> List<Q> getExcelAsFile(String file,Class<Q> cls) throws FileNotFoundException, IOException, InvalidFormatException {
        List<Q> list = new ArrayList<Q>();
        Field[] fields = cls.getDeclaredFields();
        ArrayList<String> headList = new ArrayList<String>();
        InputStream ins = null;
        Workbook wb = null;
        ins=new FileInputStream(new File(file));
        //得到Excel工作簿对象
        wb = WorkbookFactory.create(ins);
        ins.close();
        int sheetNum = wb.getNumberOfSheets();
        boolean falg = false;
        for (int i = 0; i < sheetNum; i++) {
            //得到Excel工作表对象
            Sheet sheet = wb.getSheetAt(i);
            //总行数
            int trLength = sheet.getLastRowNum();
            //数据行读取
            for (int j = 1; j < trLength+1; j++) {
                try {
                    Q shixin = cls.newInstance();
                    Row row = sheet.getRow(j);
                    falg = false;
                    for (Field f : fields) {
                        ExcelField field = f.getAnnotation(ExcelField.class);
                        if (field != null){
                            //标题行
                            Row rowt = sheet.getRow(0);
                            for (int k = 0; k < rowt.getLastCellNum(); k++) {
                                Cell cellt = rowt.getCell(k);
                                if(cellt==null){
                                    continue;
                                }
                                int cellTypet = cellt.getCellType();
                                if(cellTypet==1&&cellt.getStringCellValue().equals(field.title())){
                                    falg = true;
                                    if(row==null){
                                        continue;
                                    }
                                    Cell cell = row.getCell(k);
                                    if(cell==null){
                                        falg = false;
                                        break;
                                    }
                                    int cellType = cell.getCellType();
                                    String typeName = f.getGenericType().getTypeName();
                                    //得到单元格类型
                                    switch (cellType){
                                        case 0:
                                            //CELL_TYPE_NUMERIC
                                            f.setAccessible(true);
                                            if("java.lang.String".equals(typeName)){
                                                if(cellType == HSSFCell.CELL_TYPE_NUMERIC){
                                                    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                                                    f.set(shixin,cell.toString());
                                                }
                                            }else if("java.lang.Long".equals(typeName)){
                                                if(cellType == HSSFCell.CELL_TYPE_NUMERIC){
                                                    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                                                    f.set(shixin,Long.parseLong(cell.toString()));
                                                }
                                            }else if("java.lang.Integer".equals(typeName)){
                                                f.set(shixin,new Double(cell.getNumericCellValue()).intValue());
                                            }else if("java.lang.Double".equals(typeName)){
                                                f.set(shixin,cell.getNumericCellValue());
                                            }
                                            break;
                                        case 1:
                                            //CELL_TYPE_STRING
                                            f.setAccessible(true);
                                            if("java.lang.String".equals(typeName)){
                                                f.set(shixin,cell.getStringCellValue());
                                            }else if("java.lang.Long".equals(typeName)){
                                                if(!"".equals(cell.getStringCellValue().trim())){
                                                    f.set(shixin,Long.parseLong(cell.getStringCellValue()));
                                                }else{
                                                    falg = false;
                                                }
                                            }else if("java.lang.Integer".equals(typeName)){
                                                if(!"".equals(cell.getStringCellValue().trim())){
                                                    f.set(shixin,Integer.parseInt(cell.getStringCellValue()));
                                                }else{
                                                    falg = false;
                                                }
                                            }else if("java.lang.Double".equals(typeName)){
                                                if(!"".equals(cell.getStringCellValue().trim())){
                                                    f.set(shixin,Double.parseDouble(cell.getStringCellValue()));
                                                }else{
                                                    falg = false;
                                                }
                                            }
                                            break;
                                        case 2:
                                            //CELL_TYPE_FORMULA
                                            //cell.getCellFormula();
                                            //System.out.println(cell.getCellFormula());
                                            break;
                                        case 3:
                                            //CELL_TYPE_BLANK
                                            break;
                                        case 4:
                                            //CELL_TYPE_BOOLEAN
                                            f.setAccessible(true);
                                            if("java.lang.Boolean".equals(typeName)){
                                                f.set(shixin,cell.getBooleanCellValue());
                                            }
                                            //cell.getBooleanCellValue();
                                            //System.out.println(cell.getBooleanCellValue());
                                            break;
                                        case 5:
                                            //CELL_TYPE_ERROR
                                            //cell.getErrorCellValue();
                                            //System.out.println(cell.getErrorCellValue());
                                            break;
                                        default:
                                            break;
                                    }
                                }
                            }
                        }
                    }
                    if(falg){
                        list.add(shixin);
                    }
                } catch (InstantiationException e) {
                    log.info("第"+j+"行出错");
                    log.info(e.getMessage());
                } catch (IllegalAccessException e) {
                    log.info("第"+j+"行出错");
                    log.info(e.getMessage());
                }
            }
        }
        return list;
    }
}

execl导入封装类

完成,以上工具类已经可以导入导出了。下面来介绍下用法。

 

import com.zxy.whbackstage.common.excelUtils.ExcelField;
import lombok.Data;

@Data
public class ExportAdmin {
    @ExcelField(title = "序号")
    private Integer No;

    @ExcelField(title = "登录账号")
    private String userName;

    @ExcelField(title = "真实姓名")
    private String trueName;

    @ExcelField(title = "密码")
    private String password;

    private String gender;

    private String mobile;
}

注意看ExportAdmin这个类,你要导出哪个字段的数据就在哪个数据上标识@ExcelField(title="序号"),其中title就是对应的导出的excel的列名。

 

@RequestMapping(value = "/export", method = RequestMethod.GET)
public void exportOrderList(HttpServletResponse response){
    List<ExportAdmin> list = new ArrayList<>();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    String fileName = sdf.format(new Date())+"excel.xls";
    try {
        ExcelUtil.writeExcel(response, fileName, list, ExportAdmin.class);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

以上就是Controller调用了。list就是从后台数据库读取的ExportAdmin的集合。至此后台导出功能就完成了。下面介绍导入功能。

 

import com.zxy.whbackstage.common.excelUtils.ExcelField;
import lombok.Data;

@Data
public class InputAdmin {
    @ExcelField(title = "序号")
    private Integer No;

    @ExcelField(title = "登录账号")
    private String userName;

    @ExcelField(title = "真实姓名")
    private String trueName;

    @ExcelField(title = "密码")
    private String password;

    private String gender;

    private String mobile;
}

注意InputAdmin这个类和ExportAdmin这个类一样的呢?确实一样的,这些实体类按照你的业务需求可以合并成一个实体类。

导入和导出的正好相反,注意@ExcelField中的title,导入的excel列标题头必须和title中的中文或者英文字符相匹配。例如:

这个excel是要导入的数据,只有序号,登录账号,真实姓名,密码这4个@ExcelField标识的列的数据能读取出来,性别和手机会被忽略。

 

@ResponseBody
@RequestMapping(value = "/saveGoodsOrderFile", method = RequestMethod.POST,consumes = "multipart/form-data")
public String saveGoodsOrderFile(@RequestParam("fileName") MultipartFile file,
                                                 HttpServletRequest request) {
    // 判断文件是否为空
    if (!file.isEmpty()) {
        try {
            String filePath = request.getSession().getServletContext().getRealPath("/")+"file/temp/"
                    + file.getOriginalFilename();
            File file2=new File(filePath);
            file.transferTo(file2);
            List<InputAdmin> list = ReadExcelUtil.getExcelAsFile(filePath,InputAdmin.class);
            //this.orderChildService.saveTicketFile(list);
            if(file2.exists()){
                file2.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return "";
}

这个就是Controller调用方法,把excel文件中一行数据包装成一个InputAdmin实体类,通过工具类得到InputAdmin的List集合。至此就把excel文件里面的数据读取出来了。

 

打完收工,在此希望有大神能把我的代码优化一下,或者提供更好的工具类,欢迎斧正。

版权声明:本文为博主原创文章,未经博主允许不得转载。 

http://blog.csdn.net/tavatimsa/article/details/79636817

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值