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

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志