使用工具类简单快速导出复杂的Excel,以及下载Excel 模板

Gitee 地址如下:

https://gitee.com/xia-lijun/export-Excel.githttps://gitee.com/xia-lijun/export-Excel.git

一:首先引入pom.xml 依赖

XML 复制代码
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>eu.bitwalker</groupId>
            <artifactId>UserAgentUtils</artifactId>
            <version>1.21</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.12.1</version>
		</dependency>

二:添加工具类

接口

1.ExportedFileNameFactory

java 复制代码
public interface ExportedFileNameFactory {
    String getName(Map<String, Object> dataSource);
}

2.TemplateRenderer

java 复制代码
public interface TemplateRenderer {
    Writable render(Map<String, Object> dataSource) throws Throwable;
}

3.Writable

java 复制代码
public interface Writable {
    void write(OutputStream outputStream) throws IOException;
}
实现类:
复制代码
AbsExporter
java 复制代码
package com.example.demo.demos.exportUtils;



import com.example.demo.demos.exportUtils.interfaceUtils.TemplateRenderer;
import com.example.demo.demos.exportUtils.interfaceUtils.Writable;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Map;

/**
 * @Author 
 * @Date Created in  2024/3/15 16:58
 * @DESCRIPTION:
 * @Version V1.0
 */

public abstract class AbsExporter implements TemplateRenderer {

    public void doExport(Map<String, Object> dataSource, File exportedFile) throws Throwable {
        try(FileOutputStream fos = new FileOutputStream(exportedFile)) {
            Writable writable = this.render(dataSource);
            writable.write(fos);
        }
    }

    public abstract String getTargetFileSuffix();

    public void afterExport() {}

}
复制代码
ExcelTemplateExporter
java 复制代码
package com.example.demo.demos.exportUtils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.example.demo.demos.exportUtils.interfaceUtils.Writable;
import org.apache.poi.ss.usermodel.Workbook;

import java.util.Map;
import java.util.function.Function;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:13
 * @DESCRIPTION:
 * @Version V1.0
 */

public class ExcelTemplateExporter extends AbsExporter{
   private TemplateExportParams templateExportParams;

   private Function<Workbook, Workbook> afterRender;

   public ExcelTemplateExporter(String templateFilename) {
      this(templateFilename, null);
   }

   public ExcelTemplateExporter(String templateFilename, Function<Workbook, Workbook> afterRender) {
      this.templateExportParams = new TemplateExportParams("file/excelTemp/" + templateFilename + ".xlsx");
      this.afterRender = afterRender;
   }

   @Override
   public Writable render(Map<String, Object> dataSource) {
      Workbook workbook = ExcelExportUtil.exportExcel(this.templateExportParams, dataSource);
      if (null == workbook) {
         throw new NullPointerException("workbook 为 null");
      }
      if (this.afterRender != null) {
         workbook = this.afterRender.apply(workbook);
      }
      return new WorkbookWrapper(workbook);
   }

   @Override
   public String getTargetFileSuffix() {
      return ".xlsx";
   }

}
复制代码
ExportProcess
java 复制代码
package com.example.demo.demos.exportUtils;


import com.example.demo.demos.exportUtils.interfaceUtils.ExportedFileNameFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipOutputStream;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:00
 * @DESCRIPTION:
 * @Version V1.0
 */

public class ExportProcess {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExportProcess.class);

    /**
     * 要导出的数据源
     */
    private List<Map<String, Object>> dataSourceList = new ArrayList<>();

    /**
     * 是否为多文件导出
     */
    private boolean multiFile;

    /**
     * 导出器
     */
    private AbsExporter exporter;

    /**
     * 导出文件名
     */
    private String exportedFilename;

    /**
     * 导出为多文件时的文件名命名工厂
     */
    private ExportedFileNameFactory nameFactory;

    private ExportProcess(Map<String, Object> dataSource, AbsExporter exporter, String exportedFilename) {
        this.dataSourceList.add(dataSource);
        this.multiFile = false;
        this.exporter = exporter;
        this.exportedFilename = exportedFilename;
    }

    private ExportProcess(List<Map<String, Object>> dataSourceList, AbsExporter exporter, String exportedFilename, ExportedFileNameFactory nameFactory) {
        this.dataSourceList.addAll(dataSourceList);
        this.multiFile = true;
        this.exporter = exporter;
        this.exportedFilename = exportedFilename;
        this.nameFactory = nameFactory;
    }

    public static ExportProcess newProcess(Map<String, Object> dataSource, AbsExporter exporter, String exportedFilename) {
        return new ExportProcess(dataSource, exporter, exportedFilename);
    }

    public static ExportProcess newProcess(List<Map<String, Object>> dataSourceList, AbsExporter exporter, String exportedFilename, ExportedFileNameFactory nameFactory) {
        return new ExportProcess(dataSourceList, exporter, exportedFilename, nameFactory);
    }

    public ExportResult export() {
        ExportResult exportResult = new ExportResult(this.multiFile ? exportAsZipFile() : exportAsSingleFile());
        this.exporter.afterExport();
        return exportResult;
    }

    /**
     * 导出为单文件
     * @return 导出结果
     */
    private File exportAsSingleFile() {
        Map<String, Object> dataSource = this.dataSourceList.get(0);
        // 导出文件所在目录路径
        String exportedFileDirPath = FileUtils.filePathJoin(FileUtils.TEMP_FILE_PATH, "exportedFileDir" + UUID.randomUUID().toString());
        // 创建导出文件所在目录
        File exportedFileDir = FileUtils.createDir(exportedFileDirPath);
        String exportedFilePath = FileUtils.filePathJoin(exportedFileDirPath, this.exportedFilename + this.exporter.getTargetFileSuffix());
        File exportedFile = new File(exportedFilePath);
        try {
            this.exporter.doExport(dataSource, exportedFile);
            return exportedFile;
        } catch (Throwable t) {
            LOGGER.error(t.getMessage(), t);
            FileUtils.deleteDir(exportedFileDir);
        }
        return null;
    }

    /**
     * 导出为压缩文件
     * @return 导出结果
     */
    private File exportAsZipFile() {
        String tempFileDirPath = FileUtils.filePathJoin(FileUtils.TEMP_FILE_PATH, "tempFile" + UUID.randomUUID().toString());
        File tempFileDir = FileUtils.createDir(tempFileDirPath);
        // 导出文件所在目录路径
        String exportedFileDirPath = FileUtils.filePathJoin(FileUtils.TEMP_FILE_PATH, "exportedFileDir" + UUID.randomUUID().toString());
        // 创建导出文件所在目录
        File exportedFileDir = FileUtils.createDir(exportedFileDirPath);
        File exportedFile = new File(FileUtils.filePathJoin(exportedFileDirPath, this.exportedFilename + ".zip"));
        try {
            for (Map<String, Object> dataSource : this.dataSourceList) {
                this.exporter.doExport(dataSource, new File(FileUtils.filePathJoin(tempFileDirPath, this.nameFactory.getName(dataSource) + this.exporter.getTargetFileSuffix())));
            }
            try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(exportedFile));
                 BufferedOutputStream bos = new BufferedOutputStream(out)) {
                FileUtils.zipDir(tempFileDirPath, out, bos);
            }
            return exportedFile;
        } catch (Throwable t) {
            LOGGER.error(t.getMessage(), t);
            FileUtils.deleteDir(exportedFileDir);
        } finally {
            FileUtils.deleteDir(tempFileDir);
        }
        return null;
    }
}
复制代码
ExportResult
java 复制代码
package com.example.demo.demos.exportUtils;


import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

public class ExportResult {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExportResult.class);

    private File exportedFile;

    ExportResult(File exportedFile) {
        this.exportedFile = exportedFile;
    }

    public File getExportedFile() {
        if (null == this.exportedFile) {
            throw new NullPointerException("exportedFile 为 null");
        }
        return exportedFile;
    }

    public void download(HttpServletRequest request, HttpServletResponse response) {
        File exportedFile = getExportedFile();
        // 用于清除首部的空白行
        response.reset();
        response.setContentType("application/x-download; charset=utf-8");
        setFileDownloadHeader(request, response, this.exportedFile.getName());
        doDownload(response, exportedFile);
    }

    private void setFileDownloadHeader(HttpServletRequest request, HttpServletResponse response, String filename) {
        //获取浏览器信息
        String ua = request.getHeader("USER-AGENT");
        //转成UserAgent对象
        UserAgent userAgent = UserAgent.parseUserAgentString(ua);
        //获取浏览器信息
        Browser browser = userAgent.getBrowser();
        //浏览器名称
        String browserName = browser.getName();
        String encodedFilename;
        try {
            encodedFilename = URLEncoder.encode(filename, "UTF8");
            if (StringUtils.contains(browserName, "Internet Explorer")) {
                response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");
            } else if (StringUtils.contains(browserName, "Chrome") || StringUtils.contains(browserName, "Firefox")) {
                response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFilename);
            } else {// 其他浏览器
                response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");
            }
        } catch (UnsupportedEncodingException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    private void doDownload(HttpServletResponse response, File exportedFile) {
        OutputStream os = null;
        byte[] buffer = new byte[1024];
        BufferedInputStream bis = null;
        FileInputStream exportedFileInputStream = null;
        try {
            exportedFileInputStream = new FileInputStream(exportedFile);
            response.addHeader("content-length", exportedFileInputStream.available() + "");
            os = response.getOutputStream();
            bis = new BufferedInputStream(exportedFileInputStream);
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
            os.flush();
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            if (exportedFileInputStream != null) {
                try {
                    exportedFileInputStream.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage(), e);
                }
            }
            // 下载完成后删除临时文件
            if (exportedFile.exists()) {
                File exportedFileDir = exportedFile.getParentFile();
                FileUtils.deleteDir(exportedFileDir);
            }
        }
    }
}
复制代码
FileUtils
java 复制代码
package com.example.demo.demos.exportUtils;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:02
 * @DESCRIPTION:
 * @Version V1.0
 */

public class FileUtils {
    static {
        // 当文件系统中没有nhtemp文件夹的时候,创建
        File sf = new File(FileUtils.filePathJoin(System.getProperty("java.io.tmpdir"), "nhtemp"));
        if (!sf.exists()) {
            sf.mkdirs();
        }
    }

    /**
     * 临时文件夹,在临时文件夹中创建nhtemp,用来保存所有使用本工具类创建的文件,以便于统一清空临时文件夹,并且已经包含了文件分割符号,请注意
     */
    public static final String TEMP_FILE_PATH = FileUtils.filePathJoin(System.getProperty("java.io.tmpdir"), "nhtemp");

    /**
     * 向文件写入数据
     *
     * @param is
     * @param file
     * @throws IOException
     */
    public static void writeToFile(InputStream is, File file) throws IOException {
        FileOutputStream fs = null;
        try {
            fs = new FileOutputStream(file);
            byte[] buffer = new byte[1024];
            int byteread = 0;
            while ((byteread = is.read(buffer)) != -1) {
                fs.write(buffer, 0, byteread);
            }
        } catch (IOException e) {
            throw e;
        } finally {
            if (fs != null) {
                fs.close();
            }
            is.close();
        }
    }

    /**
     * 删除文件夹(会删除文件夹下所有的文件)
     *
     * @param dir
     * @return
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    public static File createDir(String dirPath) {
        File dir = new File(dirPath);
        //如果文件夹不存在
        if (!dir.exists()) {
            //创建文件夹
            dir.mkdir();
        }
        return dir;
    }

    public static void zipDir(String directoryName, ZipOutputStream zos, BufferedOutputStream bos) {
        File file = new File(directoryName);
        if (file.exists()) {
            File[] fileList = file.listFiles();
            assert fileList != null;
            for (File f : fileList) {
                // 压缩单个文件到 zos
                String zipName = f.getName();
                try {
                    zos.putNextEntry(new ZipEntry(zipName));
                    int len;
                    FileInputStream is = new FileInputStream(f);
                    BufferedInputStream bis = new BufferedInputStream(is);
                    byte[] bytes = new byte[1024];
                    while ((len = bis.read(bytes)) != -1) {
                        bos.write(bytes, 0, len);

                    }
                    bos.flush();
                    zos.flush();

//                    结束当前压缩文件的添加
                    bis.close();
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();

                }

            }

        }
    }

    /**
     * 路径拼接工具方法
     * @param filePath 文件路径
     * @return 拼接结果
     */
    public static String filePathJoin(String... filePath) {
        return StringUtils.join(filePath, File.separator);
    }

}
复制代码
VelocityTemplateExporter
java 复制代码
package com.example.demo.demos.exportUtils;

import cn.afterturn.easypoi.excel.ExcelXorHtmlUtil;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.example.demo.demos.exportUtils.interfaceUtils.Writable;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:08
 * @DESCRIPTION:
 * @Version V1.0
 */

public class VelocityTemplateExporter extends AbsExporter{
    private static final Logger LOGGER = LoggerFactory.getLogger(VelocityTemplateExporter.class);

    private String templateFilename;

    public VelocityTemplateExporter(String templateFilename) {
        this.templateFilename = templateFilename;
    }

    @Override
    public String getTargetFileSuffix() {
        return ".xlsx";
    }

    @Override
    public Writable render(Map<String, Object> dataSource) {
        String html = VelocityUtils.render(this.templateFilename + ".vm", dataSource);
        LOGGER.trace("渲染的html为:\n{}", html);
        Workbook workbook = ExcelXorHtmlUtil.htmlToExcel(html, ExcelType.XSSF);
        if (null == workbook) {
            throw new NullPointerException("workbook 为 null");
        }
        return new WorkbookWrapper(workbook);
    }

}
复制代码
VelocityUtils
java 复制代码
package com.example.demo.demos.exportUtils;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.VelocityException;

import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:09
 * @DESCRIPTION:
 * @Version V1.0
 */

public class VelocityUtils {
    /**
     * 模板文件所在目录
     */
    private static final String TEMPLATE_FILE_DIR = FileUtils.filePathJoin("file", "velocityTemp");

    static {
        //初始化参数
        Properties properties = new Properties();
        //设置 velocity 资源加载方式为 class
        properties.setProperty("resource.loader", "class");
        //设置 velocity 资源加载方式为 class 时的处理类
        properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        // 执行初始化
        Velocity.init(properties);
    }

    /**
     * 渲染对应模板,并输出渲染结果
     * @param templateFileName 模板文件名
     * @param velocityContext 上下文对象,即渲染使用的数据源
     * @return 渲染结果
     */
    public static String render(String templateFileName, VelocityContext velocityContext) throws VelocityException {
        StringWriter writer = new StringWriter();
        Velocity.mergeTemplate(FileUtils.filePathJoin(TEMPLATE_FILE_DIR, templateFileName), "UTF-8", velocityContext, writer);
        return writer.toString();
    }

    /**
     * 渲染对应模板,并输出渲染结果
     * @param templateFileName 模板文件名
     * @param renderDataSource 渲染使用的数据源
     * @return 渲染结果
     */
    public static String render(String templateFileName, Map<String, Object> renderDataSource) throws VelocityException {
        VelocityContext velocityContext = new VelocityContext(renderDataSource);
        return render(templateFileName, velocityContext);
    }

}
复制代码
WordTemplateExporter
java 复制代码
package com.example.demo.demos.exportUtils;

import cn.afterturn.easypoi.word.WordExportUtil;
import com.example.demo.demos.exportUtils.interfaceUtils.Writable;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.util.Map;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:16
 * @DESCRIPTION:
 * @Version V1.0
 */

public class WordTemplateExporter extends AbsExporter{
    private String templateFilePath;

    public WordTemplateExporter(String templateFilename) {
        this.templateFilePath = "file/excelTemp/" + templateFilename + ".docx";
    }

    @Override
    public String getTargetFileSuffix() {
        return ".docx";
    }

    @Override
    public Writable render(Map<String, Object> dataSource) throws Exception {
        XWPFDocument xwpfDocument = WordExportUtil.exportWord07(templateFilePath, dataSource);
        XWPFDocumentWrapper xwpfDocumentWrapper = new XWPFDocumentWrapper(xwpfDocument);
        return xwpfDocumentWrapper;
    }

}
复制代码
WorkbookWrapper
java 复制代码
package com.example.demo.demos.exportUtils;


import com.example.demo.demos.exportUtils.interfaceUtils.Writable;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.IOException;
import java.io.OutputStream;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:12
 * @DESCRIPTION:
 * @Version V1.0
 */

public class WorkbookWrapper implements Writable {
    private Workbook workbook;

    public WorkbookWrapper(Workbook workbook) {
        this.workbook = workbook;
    }

    @Override
    public void write(OutputStream outputStream) throws IOException {
        this.workbook.write(outputStream);
    }

}
复制代码
XWPFDocumentWrapper
java 复制代码
package com.example.demo.demos.exportUtils;


import com.example.demo.demos.exportUtils.interfaceUtils.Writable;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.io.IOException;
import java.io.OutputStream;


/**
 * @Author 
 * @Date Created in  2024/3/15 17:14
 * @DESCRIPTION:
 * @Version V1.0
 */

public class XWPFDocumentWrapper implements Writable {
    private XWPFDocument xwpfDocument;

    public XWPFDocumentWrapper(XWPFDocument xwpfDocument) {
        this.xwpfDocument = xwpfDocument;
    }

    @Override
    public void write(OutputStream outputStream) throws IOException {
        this.xwpfDocument.write(outputStream);
    }

}
注意:

vm 文件(自己画Excel 表格)

示例:

遍历:

XML 复制代码
## 各个列的样式,主要是加上边框
#set($style = 'style="border: 1; height:50;width:12"')
## 方法,如果存在则显示否则显示空
#macro(displayValue $value)
    #if($value)
        $value
    #else
    #end
#end

## sheetName 必须存在
<table sheetName="学生信息">
    <tr>
        <th $style>学号</th>
        <th $style>姓名</th>
        <th $style>年龄</th>
    </tr>
    #foreach($record in $maplist)
        <tr>
            <th $style>$record.xm</th>
            <th $style>$record.xb</th>
            <th $style>$record.age</th>
        </tr>
    #end
</table>

普通的方法:

XML 复制代码
## 各个列的样式,主要是加上边框
#set($style = 'style="border: 1; height:50;width:12"')
#set($height = 'style="height:30;font-size:9"')
#set($fontSize = 'style="font-size: 20;"')
## 方法,如果存在则显示否则显示空
#macro(displayValue $value)
    #if($value)
        $value
    #else
    #end
#end

## sheetName 必须存在
<table sheetName="2024第一污水处理厂再生水回用年报">
    <tr>
        <th $style colspan="8">日照市污水处理厂再生水供水年报</th>
    </tr>
    <tr>
        <th $style colspan="8">单位:第一污水处理厂       2024</th>
    </tr>
    <tr>
        <th $style>项目</th>
        <th $style rowspan="2">供水量(吨)</th>
        <th $style colspan="5">供水方向</th>
        <th $style rowspan="2">备注</th>
    </tr>
    <tr>
        <th $style>日期</th>
        <th $style>结晶集团</th>
        <th $style>香店河</th>
        <th $style>园林</th>
        <th $style>环卫</th>
        <th $style>其它</th>
    </tr>
    <tr>
        <th $style>1月</th>
        <th $style>$xm</th>
        <th $style>$yx</th>
    </tr>
    <tr>
        <th $style>2月</th>
        <th $style>$xb</th>
    </tr>
    <tr>
        <th $style>3月</th>
        <th $style>$age</th>
    </tr>
    <tr>
        <th $style>4月</th>
        <th $style>$xmm</th>
    </tr>

</table>

三:测试代码

java 复制代码
package com.example.demo.demos.controller;


import com.example.demo.demos.exportUtils.ExcelTemplateExporter;
import com.example.demo.demos.exportUtils.ExportProcess;
import com.example.demo.demos.exportUtils.VelocityTemplateExporter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author 
 * @Date Created in  2024/3/15 17:22
 * @DESCRIPTION:
 * @Version V1.0
 */
@RestController
public class ExportController {

    @GetMapping("/test")
    public void exportDownload(HttpServletRequest request, HttpServletResponse response){
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        map1.put("yf","1月");
        map1.put("xm","100");
        map1.put("xb","99");
        map1.put("age","33");
        map1.put("yx","33");
        map1.put("bj","33");
        map1.put("qs","33");
        map1.put("cs","33");

        map2.put("yf","2月");
        map2.put("xm","100000");
        map2.put("xb","200000");
        map2.put("age","300000");
        map2.put("yx","300000");
        map2.put("bj","300000");
        map2.put("qs","300000");
        map2.put("cs","300000");

        map3.put("yf","3月");
        map3.put("xm","1");
        map3.put("xb","2");
        map3.put("age","3");
        map3.put("yx","4");
        map3.put("bj","5");
        map3.put("qs","6");
        map3.put("cs","7");

        list.add(map1);
        list.add(map2);
        list.add(map3);
        Map<String, Object> map = new HashMap<>();
        map.put("maplist",list);
        ExportProcess.newProcess(map,new ExcelTemplateExporter("2024第一污水处理厂再生水回用年报"),
                "2024第一污水处理厂再生水回用年报").export().download(request,response);
//        ExportProcess.newProcess(map,new VelocityTemplateExporter("2024第一污水处理厂再生水回用年报"),
//                "2024第一污水处理厂再生水回用年报").export().download(request,response);
    }

    @GetMapping("/exportDownloadTwo")
    public void exportDownloadTwo(HttpServletRequest request, HttpServletResponse response){
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        map1.put("xm","100");
        map1.put("xb","99");
        map1.put("age","33");

        map2.put("xm","100000");
        map2.put("xb","200000");
        map2.put("age","300000");

        map3.put("xm","1");
        map3.put("xb","2");
        map3.put("age","3");

        list.add(map1);
        list.add(map2);
        list.add(map3);
        Map<String, Object> map = new HashMap<>();
        map.put("maplist",list);
//        ExportProcess.newProcess(map,new ExcelTemplateExporter("2024第一污水处理厂再生水回用年报"),
//                "2024第一污水处理厂再生水回用年报").export().download(request,response);
        ExportProcess.newProcess(map,new ExcelTemplateExporter("学生"),
                "学生").export().download(request,response);
    }
    @GetMapping("/exportDownloadTTT")
    public void exportDownloadTTT(HttpServletRequest request, HttpServletResponse response){
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        Map<String, Object> map2 = new HashMap<>();
        Map<String, Object> map3 = new HashMap<>();
        map1.put("xm","100");
        map1.put("xb","99");
        map1.put("age","33");

        map2.put("xm","100000");
        map2.put("xb","200000");
        map2.put("age","300000");

        map3.put("xm","1");
        map3.put("xb","2");
        map3.put("age","3");

        list.add(map1);
        list.add(map2);
        list.add(map3);
        Map<String, Object> map = new HashMap<>();
        map.put("maplist",list);
//        ExportProcess.newProcess(map,new ExcelTemplateExporter("2024第一污水处理厂再生水回用年报"),
//                "2024第一污水处理厂再生水回用年报").export().download(request,response);
        ExportProcess.newProcess(map,new VelocityTemplateExporter("2024第一污水处理厂再生水回用年报"),
                "2024第一污水处理厂再生水回用年报").export().download(request,response);
    }
}
第一种测试方法:

表格模板:

导出结果:

第二种测试方法:

(简单的这种,还是推荐使用EasyExcel 毕竟代码量少)

表格模板:

导出结果:

第三种测试方法:

这种需要自己画表格(没画完)

vm 文件:

XML 复制代码
## 各个列的样式,主要是加上边框
#set($style = 'style="border: 1; height:50;width:12"')
## 方法,如果存在则显示否则显示空
#macro(displayValue $value)
    #if($value)
        $value
    #else
    #end
#end

## sheetName 必须存在
<table sheetName="学生信息">
    <tr>
        <th $style>学号</th>
        <th $style>姓名</th>
        <th $style>年龄</th>
    </tr>
    #foreach($record in $maplist)
        <tr>
            <th $style>$record.xm</th>
            <th $style>$record.xb</th>
            <th $style>$record.age</th>
        </tr>
    #end
</table>

示例:

第四种测试方法:

代码:

java 复制代码
    @GetMapping("/exportDownloadTTT")
    public void exportDownloadTTT(HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> map = new HashMap<>();
        ExportProcess.newProcess(map,new ExcelTemplateExporter("2024第一污水处理厂再生水回用年报"),
             
    }

导出Excel 模板

还可以导出Word 方法类似;

相关推荐
AI科技星1 小时前
从ZUFT光速螺旋运动求导推出自然常数e
服务器·人工智能·线性代数·算法·矩阵
代码栈上的思考1 小时前
SpringBoot 拦截器
java·spring boot·spring
送秋三十五2 小时前
一次大文件处理性能优化实录————Java 优化过程
java·开发语言·性能优化
choke2332 小时前
软件测试任务测试
服务器·数据库·sqlserver
雨中飘荡的记忆2 小时前
千万级数据秒级对账!银行日终批处理对账系统从理论到实战
java
jbtianci2 小时前
Spring Boot管理用户数据
java·spring boot·后端
Sylvia-girl2 小时前
线程池~~
java·开发语言
魔力军2 小时前
Rust学习Day3: 3个小demo实现
java·学习·rust
时艰.2 小时前
java性能调优 — 高并发缓存一致性
java·开发语言·缓存
落花流水 丶2 小时前
Java 多线程完全指南
java