Java使用POI 导入导出Excel

一、使用的jar依赖版本


<dependency>
    <groupId>org.apache.poigroupId>
    <artifactId>poi-ooxmlartifactId>
    <version>3.17version>
dependency>



注:jar包poi与poi-ooxml的区别:
poi:使用前缀为HSSF的类(HSSFWorkbook),只支持2007以前的excel(文件扩展名为xls)。
poi-ooxml:使用前缀为XSSH的类(XSSFWorkbook),支持2007以前和以后的excel(文件扩展名为xlsx)。
依赖和版本的差异可能会导致代码的差异。

以下代码只支持2007以前和以后的excel(文件扩展名为xlsx。

二、工具类

package test.poi;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Excel工具类
 */
public class ExcelUtil {
	
	/**
	 * 通过模板导出excel文件
	 * 只支持 xlsx格式
	 * 只支持 读取excle第一个sheet
	 * 模板文件默认读取templates/
	 * @param dataList 数据集合
	 * @param dataEntityClass 数据实体类
	 * @param templateName 模板名称 
	 * @param titleRowNum 固定标题行数
	 * @return
	 * @throws Exception
	 */
	public static <T> ByteArrayOutputStream exportExcel(List<T> dataList, Class<T> dataEntityClass, String templateName, int titleRowNum) throws Exception {
		if (dataList == null || dataList.size() == 0) {
			throw new Exception("数据为空");
		} 
		XSSFWorkbook workbook = null;
		try {
			// 读取excel模板文件
			InputStream in = ExcelUtil.class.getClassLoader().getResourceAsStream("templates/"+templateName);
			workbook = new XSSFWorkbook(in);
	        XSSFSheet sheet = workbook.getSheetAt(0);
	        // 设置默认行高
	        //sheet.setDefaultRowHeightInPoints(25F);
	        // 获取数据实体类的所有字段
	        Field[] declaredFields = dataEntityClass.getDeclaredFields();
	        int declaredFieldsSize = declaredFields.length;
	        // ByteArray输出字节流
	        ByteArrayOutputStream baos = new ByteArrayOutputStream();
	        
	        // 遍历数据写入到excel
	        int dataListSize = dataList.size();
	        for (int i = 0; i < dataListSize; i++) { 
	        	// 获取数据list里面的对象实例
	            T instance = dataList.get(i);
	            // 创建行
	            Row row = sheet.createRow(i + titleRowNum);
	            for(int j = 0; j < declaredFieldsSize; j++){
		        	Field field = declaredFields[j];
		        	field.setAccessible(true);
		        	// 获取字段的值
		            Object value = field.get(instance);
		            
		            // 创建单元格
		            Cell cell = row.createCell(j);
		            
		            // 设置单元格样式
		            XSSFCellStyle cellStyle = workbook.createCellStyle(); 
		            
		            // 设置文本对齐方式
		            cellStyle.setWrapText(true); //设置自动换行  
		            cellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
		            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
		            
		            // 设置边框
		            cellStyle.setBorderBottom(BorderStyle.THIN); // 下边框
		            cellStyle.setBorderLeft(BorderStyle.THIN);// 左边框
		            cellStyle.setBorderTop(BorderStyle.THIN);// 上边框
		            cellStyle.setBorderRight(BorderStyle.THIN);// 右边框
		            
		            // 设置字体
		            XSSFFont font = workbook.createFont();
		            font.setFontName("宋体");// 设置字体名称
		            font.setFontHeightInPoints((short) 11);// 设置字号
		            font.setColor(IndexedColors.BLACK.index);// 设置字体颜色
		            cellStyle.setFont(font);
		            
		            cell.setCellStyle(cellStyle); 
		            cell.setCellValue(value != null ? value.toString() : "");
	            }
	        }
	        workbook.write(baos);
			return baos;
		} finally {
			try {
				if (workbook != null) {
					 workbook.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
    }
	
	/**
	 * 读取excle 
	 * 只支持 xlsx格式
	 * 只支持 读取excle第一个sheet
	 * @param excelFile excle文件
	 * @param dataEntityClass 数据实体类
	 * @param titleRowNum 固定标题行数
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> importExcel(File excelFile, Class<T> dataEntityClass, int titleRowNum) throws Exception {
		if (excelFile == null) {
			throw new Exception("参数excle文件(excelFile)不能为空");
		}
		
		XSSFWorkbook workBook = null;
		List<T> result = new ArrayList<T>();
		
		DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式化
		try {
        	// 通过excle文件构建XSSFWorkbook对象
        	workBook = new XSSFWorkbook(excelFile);
            // 获取excle第一个sheet
            XSSFSheet sheet = workBook.getSheetAt(0);
            // sheet.getFirstRowNum() 获取所有有数据的第一行索引,从0开始
            // sheet.getLastRowNum() 获取所有有数据的最后一行索引,从0开始
            for(int i = sheet.getFirstRowNum() + titleRowNum ; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                	continue;
                }
                T object = dataEntityClass.newInstance();
                Field[] fields = object.getClass().getDeclaredFields();
                Field.setAccessible(fields, true);
                
                // row.getFirstCellNum() 获取一行中有数据的列的第一列索引,从0开始
                // row.getLastCellNum() 获取一行中有数据的列的最后一列索引,从0开始
                for(int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
                    Cell cell = row.getCell(j);
                    if (cell == null) {
                    	continue;
                    }
                    Object value = null;
                    if (cell.getCellTypeEnum() == CellType.STRING) {
                    	value = cell.getStringCellValue();
                    } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
                    	if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                    		value = cell.getNumericCellValue();
            			} else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
            				value = sdf.format(cell.getDateCellValue());
            			} else {
            				value = df.format(cell.getNumericCellValue());
            			}
                    } else if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
                    	value = cell.getBooleanCellValue();
                    } else if (cell.getCellTypeEnum() == CellType.BLANK) {
                    	value = "";
                    } else {
                    	value = "";
                    }
                    Field field = fields[j];
                    Object vObj = null;
                    String vStr = value.toString();
                    if (field.getType() == String.class) {
                    	vObj = vStr;
                    } else if (field.getType() == Integer.class) {
                    	vObj = Integer.valueOf(df.format(value));
                    } else if (field.getType() == Double.class) {
                    	vObj = Double.valueOf(vStr);
                    } else if (field.getType() == Long.class) {
                    	vObj = Long.valueOf(df.format(value));
                    } else if (field.getType() == Boolean.class) {
                    	vObj = Boolean.valueOf(vStr);
                    } else {
                    	vObj = value;
                    }
                    field.set(object, vObj);
                }
                result.add(object);
                Field.setAccessible(fields, false);
            }
		} finally {
			try {
				if (workBook != null) {
					workBook.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
        return result;
    }
}

三、控制类

package test.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import test.domain.ExcelDataTest;
import test.poi.ExcelUtil;
import test.util.DownloadUtil;
import test.util.FileUtil;

@RestController
@RequestMapping("/excel")
public class ExcelController {
	
	/**
	 * 导出Excel数据
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/export" , method = RequestMethod.GET, produces = "application/json")
	public void export(HttpServletResponse response) throws Exception{
		ByteArrayOutputStream baos = null;
		OutputStream out = null;
		try {
			// excel数据  实际运用从数据库中查询
			List<ExcelDataTest> dataList = new ArrayList<ExcelDataTest>();
			ExcelDataTest data = new ExcelDataTest();
			data.setColumn1(123456);
			data.setColumn2("测试测试");
			data.setColumn3("测试测试测试测测试测试测试");
			dataList.add(data);
			
			baos = ExcelUtil.exportExcel(dataList, ExcelDataTest.class, "excel测试模板.xlsx", 2);
			DownloadUtil.generalDownload(response, baos, "excle导出测试.xlsx");
		} catch (Exception e) {
			e.printStackTrace();
		    throw new Exception("导出失败:" + e.getMessage());
		} finally {
			if(baos != null){
				baos.close();
			}
			if(out != null){
				out.close();
			}
		}
	}
	
	/**
	 * 导入Excel数据
	 * @param file
	 */
	@RequestMapping(value = "/import", method = RequestMethod.POST)
	public void importExcel(MultipartFile file) {
		File f = null;
		try {
			// MultipartFile 转  file
			f = FileUtil.multipartFileToFile(file);
			List<ExcelDataTest> list = ExcelUtil.importExcel(f, ExcelDataTest.class, 2);
			for (ExcelDataTest data : list) {
				// 实际这里是保存数据库操作
				System.out.println(data.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (f != null) {
				f.delete();
			}
		}
	}
}

下载工具类 DownloadUtil

package test.util;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

/**
 * 下载工具类
 */
public class DownloadUtil {
	
	/**
	 * 通用下载设置
	 * @param response
	 * @param outData 输出数据 ByteArrayOutputStream
	 * @param fileName 文件名
	 * @throws Exception
	 */
	public static void generalDownload(HttpServletResponse response, ByteArrayOutputStream outData, String fileName) throws Exception{
		response.setContentType( "application/x-msdownload");
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		ServletOutputStream out = response.getOutputStream();
		outData.writeTo(out);
		out.flush();
		out.close();
	}
	
	/**
	 * 通用下载设置
	 * @param response 
	 * @param outData 输出数据 InputStream
	 * @param fileName 文件名
	 * @throws Exception
	 */
	public static void generalDownload(HttpServletResponse response, InputStream outData, String fileName) throws Exception{
		response.setContentType( "application/x-msdownload");
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		ServletOutputStream out = response.getOutputStream();
		byte[] bffer = new byte[1024];
		int r = outData.read(bffer, 0, 1024);
		while (r != -1) {
			out.write(bffer);
			r = outData.read(bffer, 0, 1024);
		}
		out.flush();
		out.close();
	}
	
	/**
	 * 通用下载设置
	 * @param response 
	 * @param outData 输出数据 byte[]
	 * @param fileName 文件名
	 * @throws Exception
	 */
	public static void generalDownload(HttpServletResponse response, byte[] outData, String fileName) throws Exception{
		response.setContentType( "application/x-msdownload");
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		ServletOutputStream out = response.getOutputStream();
		out.write(outData);
		out.flush();
		out.close();
	}
}

文件工具类 FileUtil

package test.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件工具类
 */
public class FileUtil {
	
	/**
	 * MultipartFile 转  File
	 * @param file
	 * 注意:转换的文件保存在项目的根目录,因此使用完要及时清理
	 * @throws Exception
	 */
	public static File multipartFileToFile(MultipartFile multipartFile) throws Exception {
	    File toFile = null;
	    if (multipartFile != null) {
            InputStream in = multipartFile.getInputStream();
            toFile = new File(multipartFile.getOriginalFilename());
            
            OutputStream os = new FileOutputStream(toFile);
	        int r = 0;
	        byte[] buffer = new byte[1024];
	        while ((r = in.read(buffer, 0, 1024)) != -1) {
	            os.write(buffer, 0, r);
	        }
	        try {
	        	if (os != null) {
	        		os.close();
	        	}
			} catch (Exception e) {
			}
	        try {
	        	if (in != null) {
	        		in.close();
	        	}
			} catch (Exception e) {
			}
	    }
	    return toFile;
	}
	
}

数据实体类 ExcelDataTest

package test.domain;

public class ExcelDataTest {
	
	private Integer column1;
	
	private String column2;
	
	private String column3;
    
    @Override
	public String toString() {
		return "ExcelDataTest [column1=" + column1 + ", column2=" + column2 + ", column3=" + column3 + "]";
	}

	public Integer getColumn1() {
		return column1;
	}

	public void setColumn1(Integer column1) {
		this.column1 = column1;
	}

	public String getColumn2() {
		return column2;
	}

	public void setColumn2(String column2) {
		this.column2 = column2;
	}

	public String getColumn3() {
		return column3;
	}

	public void setColumn3(String column3) {
		this.column3 = column3;
	}
}

模板文件

(存放路径为src/main/resources/templates)
Java使用POI 导入导出Excel_第1张图片

四、运行结果

导出

Java使用POI 导入导出Excel_第2张图片

导入

Excel数据Java使用POI 导入导出Excel_第3张图片
结果

在这里插入图片描述

你可能感兴趣的:(Java)