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

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件