SpringBoot+POI报表批量导出

Posted 远方的夜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot+POI报表批量导出相关的知识,希望对你有一定的参考价值。

由于servletResponse 获取的输出流对象在一次请求中只能输出一次,所以要想实现批量导出报表,需要将excel文件打包成zip格式然后输出。

好了,废话不多说,上代码。

1. 首先,需要导入引用的包。pom文件如下所示(点击“+”号展开)

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.alan.demo</groupId>
    <artifactId>office2007-export</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!-- Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.ant/ant -->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.8.2</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- Spring Boot Maven 插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/libs-snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>
View Code

 

2. Controller 实现

package com.alan.demo.controller;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alan.demo.util.FileUtil;


/**
 * export batch Excel files.
 * 
 * */
@RestController
public class DataExportController {
    private static final String BASE_PATH = System.getProperty("java.io.tmpdir") + "Resource" + File.separator;
    @RequestMapping(value = "/export",method = RequestMethod.GET)
    public void export(HttpServletRequest request,  HttpServletResponse response) {
        ZipOutputStream out = null;
        BufferedInputStream bis =  null;
        InputStream in = null;
        String tip = UUID.randomUUID().toString() + File.separator;
        try {
            createAllWorkbooks(tip);
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream;charset=utf-8"); 
            response.setHeader("Content-Disposition", "attachment;filename=" + "EXCEL2016.zip");
            File tempZip = new File(BASE_PATH + tip + "temp.zip");
            FileUtil.createZipFile(new File(BASE_PATH+ tip), new ZipOutputStream(tempZip));
            System.out.println("Created ZIP File");
            OutputStream os = response.getOutputStream();
            in = new FileInputStream(tempZip);
            bis = new BufferedInputStream(in);
            byte buff[] = new byte[1024];
            int i = bis.read(buff);
            while (i != -1) {
              os.write(buff, 0, buff.length);
              os.flush();
              i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            FileUtil.deleteDir(BASE_PATH);
        }
    }
    
    /**
     * create mock data
     * 
     * */
    public List<Workbook> createAllWorkbooks(String tip) {
        List<Workbook> workbooks = new ArrayList<>();
        OutputStream out = null;
        try {
            for (int i=0;i<100;i++) {
                File tempFile = new File(BASE_PATH + tip + i + ".xlsx");
                tempFile.getParentFile().mkdirs();
                tempFile.createNewFile();
                out = new FileOutputStream(tempFile);
                Workbook workbook = new XSSFWorkbook();
                workbook.createSheet("summary");
                workbook.getSheetAt(0).createRow(0);
                Row row = workbook.getSheetAt(0).getRow(0);
                Cell cell = row.createCell(0);
                cell.setCellValue("Hello Spring Boot.");
                workbooks.add(workbook);
                workbook.write(out);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out!= null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return workbooks;
    }
}
View Code

 

3. FileUtil 工具类

package com.alan.demo.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

public class FileUtil {
    /**
     * Compress all .xlsx Files under original path.
     * 
     * */
    public static void compress(File original, ZipOutputStream out) {
        try {
            if (original == null) {
                System.err.println("Null original file is not allowed.");
            }
            if (!original.isFile()) {
                File[] files = original.listFiles();
                for (File file : files) {
                    compress(file, out);
                }
            } else if (original.isFile() && original.getName().endsWith(".xlsx")) {
                
                FileInputStream fis = new FileInputStream(original);
                int j = 0;
                byte[] buffer = new byte[1024];
                out.putNextEntry(new ZipEntry(original.getName()));
                while ((j = fis.read(buffer)) > 0) {
                    out.write(buffer, 0, j);
                }
                fis.close();
                out.flush();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Delete all files under path.
     * 
     * */
    public static boolean deleteDir(String path){  
        File file = new File(path);  
        if(!file.exists()){
            System.err.println("The dir are not exists!");  
            return false;  
        }  
          
        String[] content = file.list();
        for(String name : content){  
            File temp = new File(path, name);  
            if(temp.isDirectory()){
                deleteDir(temp.getAbsolutePath());
                temp.delete();
            }else{  
                if(!temp.delete()){
                    System.err.println("Failed to delete " + name);  
                }  
            }  
        }  
        return true;  
    }  
    
    /**
     * Create zip file
     * @param originalFile : the directory contains all files prepared to compress.
     * @param ZipOutputStream : ZIP file out put stream
     * */
    public static void createZipFile(File originalFile, ZipOutputStream out) {
        
        FileUtil.compress(originalFile, out);
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * clone input stream
     * 
     * */
    public static ByteArrayOutputStream cloneInputStream(InputStream in) {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while((len=in.read(buffer)) >0) {
                out.write(buffer, 0, len);
            }
            out.flush();
            return out;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    /*public static void main(String[] args) {
        deleteDir("C:\\\\Users\\\\mh\\\\Desktop\\\\TEMP");
    }*/
}
View Code

测试结果:

 

以上是关于SpringBoot+POI报表批量导出的主要内容,如果未能解决你的问题,请参考以下文章

springboot 实现后端接口操作Excel的导出批量导入功能

SpringBoot+POI方式导出excel加水印

SpringBoot+POI方式导出excel加水印

SpringBoot+POI方式导出excel加水印

java实现文件批量导入导出实例(兼容xls,xlsx)

基于srpingboot使用poi导出人事月度报表