Java Web利用poi导出Excel2003、2007完整解决方案

2024-02-29 21:40

本文主要是介绍Java Web利用poi导出Excel2003、2007完整解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1997-2003版行列数量限制:行-65535,列-256
2007-2010版行列数量限制:行-1048576,列-16384

根据自己的业务需求来选择版本,这里注意一下,03版本的后缀是.xls ,07版是.xlsx ,注意。本文以07版为例。

关于到导出策略,又有两种方式可供选择,一种是直接写代码来导出,但是每次都要去写表头,复制代码,这种方式的代码量比较大;另一种则是基于模板来导出,先写好表头,再填写内容,这种方式封装性比较好,代码量也较少,但会损失一部分性能。

项目是基于Maven的,下面直接上代码:

1、结构,模板和ExcelUtil放在一起
这里写图片描述

2、Maven依赖

        <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.13</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.13</version></dependency>

3、ExcelUtil

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/*** Excel导出封装类* * @author yezhiyuan* @param <T>*/
public class ExcelUtil<T> {/*** 基于Excel 2007模板写入数据* * @Title: writeExcel* @param@param file 模板文件* @param@param dataSet 数据集* @param@throws IOException* @param@throws NoSuchMethodException* @param@throws SecurityException* @param@throws InvocationTargetException* @return:void* @author yezhiyuan* @date 2017-3-14 下午3:13:12* @throws*/@SuppressWarnings("unused")public void writeExcel(File file,Collection<T> dataSet) throws IOException, NoSuchMethodException,SecurityException, InvocationTargetException {XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(file));XSSFSheet sheet = workbook.getSheetAt(0);// 写入内容Iterator<T> iterator = dataSet.iterator();int index = 1;while (iterator.hasNext()) {XSSFRow row = sheet.createRow(index);T t = (T) iterator.next();// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值Field[] fields = t.getClass().getDeclaredFields();for (short i = 0; i < fields.length; i++) {if (i == 0) {XSSFCell cell = row.createCell(i);cell.setCellValue(index);cell = row.createCell(i + 1);fields[i].setAccessible(true);try {String fieldName = fields[i].getName();String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);Object valueObject = fields[i].get(t);Class<? extends Object> tCls = t.getClass();Method getMethod = tCls.getMethod(getMethodName,new Class[]{});Object value = getMethod.invoke(t, new Object[]{});if (valueObject instanceof String) {cell.setCellValue(valueObject.toString());} else {cell.setCellValue(valueObject + "");}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}} else {XSSFCell cell = row.createCell(i + 1);fields[i].setAccessible(true);try {String fieldName = fields[i].getName();String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);Object valueObject = fields[i].get(t);Class<? extends Object> tCls = t.getClass();Method getMethod = tCls.getMethod(getMethodName,new Class[]{});Object value = getMethod.invoke(t, new Object[]{});if (valueObject instanceof String) {if (valueObject == null) {cell.setCellValue("");} else {cell.setCellValue(valueObject.toString());}} else if (valueObject instanceof BigDecimal) {BigDecimal vDecimal = (BigDecimal) value;cell.setCellValue(vDecimal.doubleValue());} else if (valueObject instanceof Integer) {cell.setCellValue((Integer) valueObject);} else if (valueObject instanceof Double) {cell.setCellValue((Double) valueObject);} else {if (valueObject == null) {cell.setCellValue("");} else {cell.setCellValue(valueObject.toString());}}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}index++;}OutputStream outputStream = new FileOutputStream(file);workbook.write(outputStream);outputStream.close();}/*** 下载Excel* * @param request* @param response* @param list 要导出的数据* @param model  模板名称* @param name 导出Excel文件名* @return* @throws IOException*/public void download(HttpServletRequest request,HttpServletResponse response,List<T> list,String model,String name) throws IOException {ServletOutputStream out = null;FileInputStream inputStream = null;try {response.setContentType("multipart/form-data");String path = ExcelUtil.class.getResource("").getPath();// 获取模板路径path += model + ".xlsx";//excel模板String fileName = name +"_" + System.currentTimeMillis() + ".xlsx";response.setHeader("Content-Disposition","attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));FileUtils.Copy(path, path + fileName);File file = new File(path + fileName);writeExcel(file, list);//组装数据out = response.getOutputStream();inputStream = new FileInputStream(file);int b = 0;byte[] buffer = new byte[4096];while ((b = inputStream.read(buffer)) != -1) {out.write(buffer, 0, b);}} catch (Exception e) {e.printStackTrace();} finally {inputStream.close();out.close();out.flush();}}/*** 基于Excel 2003模板写入数据* * @Title: writeExcelContent* @param@param file* @param@param dataSet* @param@throws IOException* @param@throws NoSuchMethodException* @param@throws SecurityException* @param@throws InvocationTargetException* @return:void* @Description:TODO()* @date * @throws*/@SuppressWarnings("unused")public void writeExcel2003(File file, Collection<T> dataSet)throws IOException, NoSuchMethodException, SecurityException,InvocationTargetException {HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(file));HSSFSheet sheet = workbook.getSheetAt(0);// 写入内容Iterator<T> iterator = dataSet.iterator();int index = 1;while (iterator.hasNext()) {HSSFRow row = sheet.createRow(index);T t = (T) iterator.next();// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值Field[] fields = t.getClass().getDeclaredFields();for (short i = 0; i < fields.length; i++) {if (i == 0) {@SuppressWarnings("deprecation")HSSFCell cell = row.createCell(i);cell.setCellValue(index);cell = row.createCell(i + 1);fields[i].setAccessible(true);try {String fieldName = fields[i].getName();String getMethodName = "get"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);Object valueObject = fields[i].get(t);Class<? extends Object> tCls = t.getClass();Method getMethod = tCls.getMethod(getMethodName,new Class[]{});Object value = getMethod.invoke(t, new Object[]{});if (valueObject instanceof String) {cell.setCellValue(valueObject.toString());} else {cell.setCellValue(valueObject + "");}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}} else {HSSFCell cell = row.createCell(i + 1);fields[i].setAccessible(true);try {String fieldName = fields[i].getName();String getMethodName = "get"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);Object valueObject = fields[i].get(t);Class<? extends Object> tCls = t.getClass();Method getMethod = tCls.getMethod(getMethodName,new Class[]{});Object value = getMethod.invoke(t, new Object[]{});if (valueObject instanceof String) {if (valueObject == null) {cell.setCellValue("");} else {cell.setCellValue(valueObject.toString());}} else if (valueObject instanceof BigDecimal) {BigDecimal vDecimal = (BigDecimal) value;cell.setCellValue(vDecimal.doubleValue());} else if (valueObject instanceof Integer) {cell.setCellValue((Integer) valueObject);} else if (valueObject instanceof Double) {cell.setCellValue((Double) valueObject);} else {if (valueObject == null) {cell.setCellValue("");} else {cell.setCellValue(valueObject.toString());}}} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}index++;}OutputStream outputStream = new FileOutputStream(file);workbook.write(outputStream);outputStream.close();}
}

4、FileUtils

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class FileUtils {private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);/*** Construct a file from the set of name elements.* * @param directory*            the parent directory* @param names*            the name elements* @return the file*/public static File getFile(File directory, String... names) {if (directory == null) {throw new NullPointerException("directorydirectory must not be null");}if (names == null) {throw new NullPointerException("names must not be null");}File file = directory;for (String name : names) {file = new File(file, name);}return file;}public static void Copy(String oldPath, String newPath)throws IOException {int byteread = 0;File oldfile = new File(oldPath);if (oldfile.exists()) {InputStream inStream = new FileInputStream(oldPath);FileOutputStream fs = new FileOutputStream(newPath);byte[] buffer = new byte[1444];while ((byteread = inStream.read(buffer)) != -1) {fs.write(buffer, 0, byteread);}inStream.close();} else {logger.error("文件不存在:{}",oldPath);}}/*** Construct a file from the set of name elements.* * @param names*            the name elements* @return the file*/public static File getFile(String... names) {if (names == null) {throw new NullPointerException("names must not be null");}File file = null;for (String name : names) {if (file == null) {file = new File(name);} else {file = new File(file, name);}}return file;}/*** Opens a {@link FileInputStream} for the specified file, providing better* error messages than simply calling <code>new FileInputStream(file)</code>* .* <p>* At the end of the method either the stream will be successfully opened,* or an exception will have been thrown.* <p>* An exception is thrown if the file does not exist. An exception is thrown* if the file object exists but is a directory. An exception is thrown if* the file exists but cannot be read.* * @param file*            the file to open for input, must not be {@code null}* @return a new {@link FileInputStream} for the specified file* @throws FileNotFoundException*             if the file does not exist* @throws IOException*             if the file object is a directory* @throws IOException*             if the file cannot be read*/public static FileInputStream openInputStream(File file) throws IOException {if (file.exists()) {if (file.isDirectory()) {throw new IOException("File '" + file+ "' exists but is a directory");}if (file.canRead() == false) {throw new IOException("File '" + file + "' cannot be read");}} else {throw new FileNotFoundException("File '" + file+ "' does not exist");}return new FileInputStream(file);}/*** 创建文件* * @param path* @param fileName* @return*/public static File createFile(String path, String fileName) {File file = new File(path);if (!file.exists()) {file.mkdir();}file = new File(path, fileName);try {file.createNewFile();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return file;}/*** Opens a {@link FileOutputStream} for the specified file, checking and* creating the parent directory if it does not exist.* <p>* At the end of the method either the stream will be successfully opened,* or an exception will have been thrown.* <p>* The parent directory will be created if it does not exist. The file will* be created if it does not exist. An exception is thrown if the file* object exists but is a directory. An exception is thrown if the file* exists but cannot be written to. An exception is thrown if the parent* directory cannot be created.* * @param file*            the file to open for output, must not be {@code null}* @param append*            if {@code true}, then bytes will be added to the end of the*            file rather than overwriting* @return a new {@link FileOutputStream} for the specified file* @throws IOException*             if the file object is a directory* @throws IOException*             if the file cannot be written to* @throws IOException*             if a parent directory needs creating but that fails*/public static FileOutputStream openOutputStream(File file, boolean append)throws IOException {if (file.exists()) {if (file.isDirectory()) {throw new IOException("File '" + file+ "' exists but is a directory");}if (file.canWrite() == false) {throw new IOException("File '" + file+ "' cannot be written to");}} else {File parent = file.getParentFile();if (parent != null) {if (!parent.mkdirs() && !parent.isDirectory()) {throw new IOException("Directory '" + parent+ "' could not be created");}}}return new FileOutputStream(file, append);}public static FileOutputStream openOutputStream(File file)throws IOException {return openOutputStream(file, false);}/*** Cleans a directory without deleting it.* * @param directory*            directory to clean* @throws IOException*             in case cleaning is unsuccessful*/public static void cleanDirectory(File directory) throws IOException {if (!directory.exists()) {String message = directory + " does not exist";throw new IllegalArgumentException(message);}if (!directory.isDirectory()) {String message = directory + " is not a directory";throw new IllegalArgumentException(message);}File[] files = directory.listFiles();if (files == null) { // null if security restrictedthrow new IOException("Failed to list contents of " + directory);}IOException exception = null;for (File file : files) {try {forceDelete(file);} catch (IOException ioe) {exception = ioe;}}if (null != exception) {throw exception;}}/*** 创建目录* * @Title: createDirectory* @param:@param directoryPath* @param:@return* @return:boolean* @Description:TODO(这里用一句话描述这个方法的作用)* @author liuping* @date 2016-9-9 上午11:31:37* @throws*/public static boolean createDirectory(String directoryPath) {boolean bFlag = false;try {File file = new File(directoryPath.toString());if (!file.exists()) {bFlag = file.mkdir();}} catch (Exception e) {e.printStackTrace();}return bFlag;}// -----------------------------------------------------------------------/*** Deletes a directory recursively.* * @param directory*            directory to delete* @throws IOException*             in case deletion is unsuccessful*/public static void deleteDirectory(File directory) throws IOException {if (!directory.exists()) {return;}cleanDirectory(directory);if (!directory.delete()) {String message = "Unable to delete directory " + directory + ".";throw new IOException(message);}}/*** Deletes a file. If file is a directory, delete it and all* sub-directories.* <p>* The difference between File.delete() and this method are:* <ul>* <li>A directory to be deleted does not have to be empty.</li>* <li>You get exceptions when a file or directory cannot be deleted.* (java.io.File methods returns a boolean)</li>* </ul>* * @param file*            file or directory to delete, must not be {@code null}* @throws NullPointerException*             if the directory is {@code null}* @throws FileNotFoundException*             if the file was not found* @throws IOException*             in case deletion is unsuccessful*/public static void forceDelete(File file) throws IOException {if (file.isDirectory()) {deleteDirectory(file);} else {boolean filePresent = file.exists();if (!file.delete()) {if (!filePresent) {throw new FileNotFoundException("File does not exist: "+ file);}String message = "Unable to delete file: " + file;throw new IOException(message);}}}/*** Deletes a file, never throwing an exception. If file is a directory,* delete it and all sub-directories.* <p>* The difference between File.delete() and this method are:* <ul>* <li>A directory to be deleted does not have to be empty.</li>* <li>No exceptions are thrown when a file or directory cannot be deleted.</li>* </ul>* * @param file*            file or directory to delete, can be {@code null}* @return {@code true} if the file or directory was deleted, otherwise*         {@code false}* */public static boolean deleteQuietly(File file) {if (file == null) {return false;}try {if (file.isDirectory()) {cleanDirectory(file);}} catch (Exception ignored) {}try {return file.delete();} catch (Exception ignored) {return false;}}/*** Makes a directory, including any necessary but nonexistent parent* directories. If a file already exists with specified name but it is not a* directory then an IOException is thrown. If the directory cannot be* created (or does not already exist) then an IOException is thrown.* * @param directory*            directory to create, must not be {@code null}* @throws NullPointerException*             if the directory is {@code null}* @throws IOException*             if the directory cannot be created or the file already exists*             but is not a directory*/public static void forceMkdir(File directory) throws IOException {if (directory.exists()) {if (!directory.isDirectory()) {String message = "File " + directory + " exists and is "+ "not a directory. Unable to create directory.";throw new IOException(message);}} else {if (!directory.mkdirs()) {// Double-check that some other thread or process hasn't made// the directory in the backgroundif (!directory.isDirectory()) {String message = "Unable to create directory " + directory;throw new IOException(message);}}}}/*** Returns the size of the specified file or directory. If the provided* {@link File} is a regular file, then the file's length is returned. If* the argument is a directory, then the size of the directory is calculated* recursively. If a directory or subdirectory is security restricted, its* size will not be included.* * @param file*            the regular file or directory to return the size of (must not*            be {@code null}).* * @return the length of the file, or recursive size of the directory,*         provided (in bytes).* * @throws NullPointerException*             if the file is {@code null}* @throws IllegalArgumentException*             if the file does not exist.* */public static long sizeOf(File file) {if (!file.exists()) {String message = file + " does not exist";throw new IllegalArgumentException(message);}if (file.isDirectory()) {return sizeOfDirectory(file);} else {return file.length();}}/*** Counts the size of a directory recursively (sum of the length of all* files).* * @param directory*            directory to inspect, must not be {@code null}* @return size of directory in bytes, 0 if directory is security*         restricted, a negative number when the real total is greater than*         {@link Long#MAX_VALUE}.* @throws NullPointerException*             if the directory is {@code null}*/public static long sizeOfDirectory(File directory) {checkDirectory(directory);final File[] files = directory.listFiles();if (files == null) { // null if security restrictedreturn 0L;}long size = 0;for (final File file : files) {size += sizeOf(file);if (size < 0) {break;}}return size;}/*** Checks that the given {@code File} exists and is a directory.* * @param directory*            The {@code File} to check.* @throws IllegalArgumentException*             if the given {@code File} does not exist or is not a*             directory.*/private static void checkDirectory(File directory) {if (!directory.exists()) {throw new IllegalArgumentException(directory + " does not exist");}if (!directory.isDirectory()) {throw new IllegalArgumentException(directory+ " is not a directory");}}
}

5、模板test.xlsx
这里写图片描述

6、实体类User

public class User {
private Integer id;
private Integer age;
private String name;
//省略get、set方法
}

7、Controller的写法

    @RequestMapping(value = "/excel")@ResponseBodypublic void excelTest(HttpServletRequest request,HttpServletResponse response) throws IOException {ExcelUtil<User> vExcelUtil = new ExcelUtil<User>();//导出类初始化List<User> list = new ArrayList<>();User user1 = new User();user1.setId(55);user1.setAge(20);user1.setName("刘德华");User user2 = new User();user2.setId(66);user2.setAge(30);user2.setName("张学友");User user3 = new User();user3.setId(88);user3.setAge(40);user3.setName("黎明");list.add(user1);list.add(user2);list.add(user3);vExcelUtil.download(request, response, list,"test","导出测试的数据");}

8、浏览器输入:http://localhost:8080/excel

9、导出效果
这里写图片描述

特别注意:由于是使用反射来写数据到excel,所以表头的顺序要和实体类属性一致。

这篇关于Java Web利用poi导出Excel2003、2007完整解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760186

相关文章

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

Spring Boot项目打包和运行的操作方法

《SpringBoot项目打包和运行的操作方法》SpringBoot应用内嵌了Web服务器,所以基于SpringBoot开发的web应用也可以独立运行,无须部署到其他Web服务器中,下面以打包dem... 目录一、打包为JAR包并运行1.打包为可执行的 JAR 包2.运行 JAR 包二、打包为WAR包并运行

Java进行日期解析与格式化的实现代码

《Java进行日期解析与格式化的实现代码》使用Java搭配ApacheCommonsLang3和Natty库,可以实现灵活高效的日期解析与格式化,本文将通过相关示例为大家讲讲具体的实践操作,需要的可以... 目录一、背景二、依赖介绍1. Apache Commons Lang32. Natty三、核心实现代

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Spring Boot 常用注解整理(最全收藏版)

《SpringBoot常用注解整理(最全收藏版)》本文系统整理了常用的Spring/SpringBoot注解,按照功能分类进行介绍,每个注解都会涵盖其含义、提供来源、应用场景以及代码示例,帮助开发... 目录Spring & Spring Boot 常用注解整理一、Spring Boot 核心注解二、Spr

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

如何合理管控Java语言的异常

《如何合理管控Java语言的异常》:本文主要介绍如何合理管控Java语言的异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、Thorwable类3、Error4、Exception类4.1、检查异常4.2、运行时异常5、处理方式5.1. 捕获异常

Spring Boot集成SLF4j从基础到高级实践(最新推荐)

《SpringBoot集成SLF4j从基础到高级实践(最新推荐)》SLF4j(SimpleLoggingFacadeforJava)是一个日志门面(Facade),不是具体的日志实现,这篇文章主要介... 目录一、日志框架概述与SLF4j简介1.1 为什么需要日志框架1.2 主流日志框架对比1.3 SLF4