java使用freemarker导出复杂的excel表格

正常导出excel表格使用的poi,但是导出复杂的excel有点困难,但是可以使用freemaker模板来导出复杂的excel。

  • 都是先生成一个Excel表格的模板,最好是增加一行数据。具体看图里面的步骤。
    在这里插入图片描述

  • 项目整体结构
    在这里插入图片描述

  • 下面就直接看代码

public class Data {
//代码复制之后直接就可以运行了
    public static void main(String[] args) {
        demo();
    }

    public static void demo() {
        // 项目下的template路径
        String path = new File("").getAbsolutePath() + "\\template";
        Map<String, Object> map = new HashMap<String, Object>();
        // 模板所在的路径
        map.put("tempFoldPath", path);
        // 生成的路径
        map.put("file", path + "/采购订单.xls");
        // 模板名称
        map.put("tampPath", "采购订单.ftl");
        // 最后生成的表格的名称
        map.put("excelName", "采购订单-" + "Demo" + ".xls");
        // 封装数据
        Map<String, Object> exlParam = new HashMap<>();
        exlParam.put("findList", new Data().list());
        // 调用方法,返回浏览器访问的地址
        String downloadUrl = ExportExcelUtil.exportExcel(map, exlParam);
    }

    // 自己造假数据,正常来说都是从数据库查询出来拼装数据的
    public List<Purbill> list() {
        List<Purbill> purbillList = new ArrayList<>();
        purbillList.add(new Purbill("1", "2", "名称", "采购名称", "规格参数", "参数指标", "场地", "10吨", 10, 20.2, 220.2, "品牌"));
        return purbillList;
    }

}

class Purbill {
    private String bidId;
    private String billno;
    private String categoryName;
    private String purname;
    private String specparams;
    private String paramnorm;
    private String productAddress;
    private String unit;
    private Integer nums;
    private Double price;
    private Double totalprice;
    private String brand;

    public Purbill(String bidId, String billno, String categoryName, String purname, String specparams,
            String paramnorm, String productAddress, String unit, Integer nums, Double price, Double totalprice,
            String brand) {
        super();
        this.bidId = bidId;
        this.billno = billno;
        this.categoryName = categoryName;
        this.purname = purname;
        this.specparams = specparams;
        this.paramnorm = paramnorm;
        this.productAddress = productAddress;
        this.unit = unit;
        this.nums = nums;
        this.price = price;
        this.totalprice = totalprice;
        this.brand = brand;
    }

    public String getBidId() {
        return bidId;
    }

    public void setBidId(String bidId) {
        this.bidId = bidId;
    }

    public String getBillno() {
        return billno;
    }

    public void setBillno(String billno) {
        this.billno = billno;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public String getPurname() {
        return purname;
    }

    public void setPurname(String purname) {
        this.purname = purname;
    }

    public String getSpecparams() {
        return specparams;
    }

    public void setSpecparams(String specparams) {
        this.specparams = specparams;
    }

    public String getParamnorm() {
        return paramnorm;
    }

    public void setParamnorm(String paramnorm) {
        this.paramnorm = paramnorm;
    }

    public String getProductAddress() {
        return productAddress;
    }

    public void setProductAddress(String productAddress) {
        this.productAddress = productAddress;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public Integer getNums() {
        return nums;
    }

    public void setNums(Integer nums) {
        this.nums = nums;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Double getTotalprice() {
        return totalprice;
    }

    public void setTotalprice(Double totalprice) {
        this.totalprice = totalprice;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

}

主要是两个map,一个map是封装模板的位置和生成表格的位置,第二个map是封装的数据。正常来说导出表格之后都是返回url请求的地址,这样在真实项目中根据地址就可以下载出来了。

  • 下面是一个excel导出的一个工具类
public class ExportExcelUtil {

    public static String exportExcel(Map<String, Object> map, Map<String, Object> exlParam) {
        Template dateTmp = null;
        Writer fw = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            // 此处需要给你个版本信息,Configuration cfg = new Configuration();这个方法已经过时了
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
            String tempFoldPath = (String) map.get("tempFoldPath"); // 模板所在的路径
            String file = (String) map.get("file");// 生成表格模板的路径
            String tampPath = (String) map.get("tampPath");// 模板名称
            String excelName = (String) map.get("excelName");// 最后生成表格的名称

            // **********初始化参数**********
            File tempFoldFile = new File(tempFoldPath);
            if (!tempFoldFile.exists()) {
                tempFoldFile.mkdirs();
            }
            cfg.setDirectoryForTemplateLoading(tempFoldFile);
            cfg.setDefaultEncoding("UTF-8");
            cfg.setTemplateUpdateDelay(0);
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
            // **********获取freemaker模板**********
            dateTmp = cfg.getTemplate(tampPath);

            // **********将数据写入freemaker模板**********
            fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(file)), "UTF-8"));
            dateTmp.process(exlParam, fw);

            // **********从freemaker模板读出数据写到Excel表格并生成出来**********
            String fileDir = "excel";
            // 文件保存目录  项目目录下面
            String filePath =  new File("").getAbsolutePath();
            // 生成保存文件路径
            String createPath = filePath + "/" + fileDir + "/";
            // 构建源文件
            File files = new File(file);
            // 文件夹不存在就创建
            createFolder(createPath);
            // 删除原来的文件
            deleteFile(createPath + excelName);
            // 构建目标文件
            File fileCopy = new File(createPath + excelName);
            // 目标文件不存在就创建
            if (!(fileCopy.exists())) {
                fileCopy.createNewFile();
            }
            // 源文件创建输入流
            in = new FileInputStream(files);
            // 目标文件创建输出流
            out = new FileOutputStream(fileCopy, true);
            // 创建字节数组
            byte[] temp = new byte[1024];
            int length = 0;
            // 源文件读取一部分内容
            while ((length = in.read(temp)) != -1) {
                // 目标文件写入一部分内容
                out.write(temp, 0, length);
            }
            // 资源服务器访问目录 这边需要配置tomcat的虚拟路径,就可以直接在url上面下载表格了
            String serverPath = "resourceServer";
            String savePath = "/" + serverPath + "/" + fileDir + "/" + excelName;
            // 服务器图片访问目录
            return savePath;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                fw.close();
                // 关闭文件输入输出流
                in.close();
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

    // 创建文件
    public static boolean createFolder(String path) {
        File file = new File(path);
        if (!file.exists()) {
            return file.mkdir();
        } else {
            return true;
        }
    }

    public static boolean deleteFile(String filePath) {// 删除单个文件
        boolean flag = false;
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            file.delete();// 文件删除
            flag = true;
        }
        return true;
    }

}

这个也不用多说,里面注释基本上已经解释清楚了,

  • 因为数据放到freemaker模板里面了所以只需要使用freemaker模板的语法取出数据存放在模板里面就可以了
    在这里插入图片描述

  • Excel导出打开出现问题的原因
    当office2010之前的版本打开会出现格式不正确的提示,然后点击确定之后还是报格式错误或者可以打开但是没有数据,这种解决方法只需要将ss:ExpandedRowCount这个值设置和行数相等或者设置大一点就不会出现这种问题了。
    在这里插入图片描述

    错误提示
    在这里插入图片描述

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用Freemarker动态生成HTML表格,您可以按照以下步骤: 1. 导入Freemarker依赖 如果您正在使用Maven或Gradle等构建工具,可以将Freemarker添加到项目的依赖中。以下是Maven的依赖: ``` <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.31</version> </dependency> ``` 2. 创建模板文件 在模板文件中,您可以使用Freemarker的语法来定义HTML表格的结构和样式。例如,以下是一个简单的模板文件,它定义了一个包含表头和表格数据的HTML表格: ``` <table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Email</th> </tr> </thead> <tbody> <#list users as user> <tr> <td>${user.name}</td> <td>${user.age}</td> <td>${user.email}</td> </tr> </#list> </tbody> </table> ``` 在模板文件中,`${user.name}`、`${user.age}`和`${user.email}`是Freemarker表达式,它们将在渲染模板时被替换为实际的用户数据。 3. 准备数据 在Java代码中,您需要准备数据以便在模板中使用。您可以将数据放在一个Map对象中,其中每个键值对表示模板中的一个变量和它的值。例如,以下是一个包含三个用户的Map对象: ``` Map<String, Object> data = new HashMap<>(); List<User> users = Arrays.asList( new User("Alice", 30, "alice@example.com"), new User("Bob", 25, "bob@example.com"), new User("Charlie", 35, "charlie@example.com") ); data.put("users", users); ``` 在这里,User是一个自定义的Java类,它具有三个属性:name、age和email。 4. 渲染模板 最后,您需要将数据应用于模板并生成HTML表格。以下是一个简单的方法,使用Freemarker的Template和TemplateExceptionHandler类来完成这个任务: ``` public String generateTable(Map<String, Object> data) throws Exception { Configuration cfg = new Configuration(Configuration.VERSION_2_3_31); cfg.setClassForTemplateLoading(getClass(), "/templates"); cfg.setDefaultEncoding("UTF-8"); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); Template template = cfg.getTemplate("table.ftl"); StringWriter out = new StringWriter(); template.process(data, out); return out.toString(); } ``` 在这里,“/templates”是存放模板文件的目录,table.ftl是您之前创建的模板文件的名称。当process方法被调用时,Freemarker使用data中的数据替换模板文件中的表达式,并将结果写入StringWriter对象中。最后,该方法将返回生成的HTML表格字符串。 希望这个简单的例子能帮助您入门Fre ### 回答2: 使用Java中的Freemarker库动态生成HTML表格,需要以下步骤: 1. 导入Freemarker库:首先需要在Java项目中导入Freemarker库。可以通过Maven或手动下载jar文件导入。 2. 创建Freemarker配置对象:创建Configuration对象,并进行必要的配置,如设置模板文件的加载路径等。 3. 创建数据模型:创建一个Java对象,用于存储要在HTML表格中展示的数据。可以包含多个属性,比如姓名、年龄等。 4. 加载模板文件:使用Configuration对象加载HTML表格的模板文件。可以是一个已经存在的HTML文件,通过Freemarker的模板语法嵌入需要动态生成的内容。 5. 创建数据模型集合:如果需要在表格中展示多条数据,可以创建一个List或数组,将多个数据模型对象添加到集合中。 6. 填充数据到模板:创建一个Template对象,并使用数据模型集合作为参数,调用process方法将数据填充到模板中。 7. 输出生成的HTML表格:将填充好数据的模板内容输出到一个HTML文件或直接返回给用户。 以下是一个简单的示例代码: ```java import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class FreemarkerExample { public static void main(String[] args) { try { // 创建Freemarker配置对象 Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); cfg.setClassForTemplateLoading(FreemarkerExample.class, "/templates"); // 创建数据模型 List<Map<String, Object>> dataModels = new ArrayList<>(); Map<String, Object> dataModel1 = new HashMap<>(); dataModel1.put("name", "John"); dataModel1.put("age", 25); dataModels.add(dataModel1); Map<String, Object> dataModel2 = new HashMap<>(); dataModel2.put("name", "Alice"); dataModel2.put("age", 30); dataModels.add(dataModel2); // 加载模板文件 Template template = cfg.getTemplate("table_template.ftl"); // 填充数据到模板 Writer out = new OutputStreamWriter(System.out); template.process(dataModels, out); // 输出生成的HTML表格 out.flush(); } catch (IOException | TemplateException e) { e.printStackTrace(); } } } ``` 示例中使用了一个名为`table_template.ftl`的模板文件作为HTML表格的模板,模板中可以使用Freemarker的模板语法嵌入动态生成的内容。 以上就是使用Java中的Freemarker库动态生成HTML表格的基本流程,你可以根据实际需求进行修改和扩展。 ### 回答3: 使用Java中的Freemarker库来动态生成HTML表格可以分为以下几个步骤: 1. 引入Freemarker库:传统的方式是下载Freemarker库的jar文件然后将其添加到项目的classpath中。现代方式是使用构建工具如Maven或Gradle来管理依赖。 2. 创建Freemarker配置对象:使用Freemarker的Configuration类来创建一个配置对象。可以通过指定模板文件夹的路径来告诉Freemarker在哪里读取模板。 3. 加载模板:使用配置对象的getTemplate方法来加载模板文件。需要传入模板文件的路径和名称。 4. 创建数据模型:创建一个Java对象作为数据模型,然后将需要在表格中展示的数据放入该对象中。可以使用Map或者POJO来代表数据模型。 5. 合并数据模型和模板:创建一个Writer对象来存储生成的HTML代码。然后使用模板对象的process方法将数据模型和Writer对象作为参数传入,生成HTML代码。 6. 输出HTML代码:将Writer对象中的HTML代码输出到文件或者直接返回给HTTP响应。 总的来说,使用Freemarker库生成HTML表格主要涉及创建Freemarker配置对象、加载模板、创建数据模型、合并数据模型和模板,并最终输出HTML代码。较为复杂表格可以在模板文件中使用Freemarker的标签和指令来实现动态处理和逻辑控制,以实现更高级的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值