国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用freemarker,導(dǎo)出制作好的ftl模板,并寫入數(shù)據(jù)

這篇具有很好參考價(jià)值的文章主要介紹了使用freemarker,導(dǎo)出制作好的ftl模板,并寫入數(shù)據(jù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

使用freemarker,導(dǎo)出制作好的ftl模板,并寫入數(shù)據(jù)

一、背景

1.1 項(xiàng)目背景

  • 最近在開發(fā)一個(gè)項(xiàng)目,需要導(dǎo)出一些數(shù)據(jù),然后寫入到word文檔中,然后再導(dǎo)出到本地,這個(gè)需求是比較常見的,但是我在網(wǎng)上找了很多資料,都沒(méi)有找到一個(gè)比較好的解決方案,所以就自己寫了一個(gè),這里分享給大家,希望能幫助到大家。
  • 項(xiàng)目中使用的技術(shù)棧:freemarker
  • 項(xiàng)目中使用的依賴:
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>

二、實(shí)現(xiàn)

2.1 代碼實(shí)現(xiàn)

  • 代碼實(shí)現(xiàn)比較簡(jiǎn)單,就是先制作好ftl模板,然后在模板中標(biāo)記好需要寫入的數(shù)據(jù)的位置,然后在代碼中將數(shù)據(jù)寫入到模板中,然后再導(dǎo)出到本地,具體代碼如下:
  • 1.首先創(chuàng)建一個(gè)ftl模板,這里我創(chuàng)建了一個(gè)test.ftl模板,模板中的內(nèi)容如下:
<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${user}!</h1>
  <p>We have there animals:
  <ul>
  <list animals as animal>
    <li>${animal.name} for ${animal.price} Euros
  </list>
  </ul>
  <include "common_footer.html">
</body>
</html>
  • 2.然后在查詢數(shù)據(jù)中定義數(shù)據(jù)對(duì)象,使用@ExportWordField注解標(biāo)記需要寫入的數(shù)據(jù),具體代碼如下:
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExportWordField {

    //字段名稱
    String fieldName() default "";

    //是否是文件名稱字段,只有導(dǎo)出zip時(shí)才會(huì)用到
    boolean isFileNameFiled() default false;

    //文件名稱字段排序,只有導(dǎo)出zip時(shí)才會(huì)用到
    int fileNameFiledSort() default 0;
}
//測(cè)試數(shù)據(jù)對(duì)象
@Data
public class Something{
    @ExportWordField(fieldName = "user",isFileNameFiled = true,fileNameFiledSort = 1)
    private String user;
    @ExportWordField(fieldName = "animals")
    private List<Animal> animals;
}

@Data
public class Animal{
    @ExportWordField(fieldName = "name")
    private String name;
    @ExportWordField(fieldName = "price")
    private String price;
}
  • 3.然后在代碼中將數(shù)據(jù)寫入到模板中,具體代碼如下:
@Slf4j
public class ExportTemplateUtil {

    private static final String DOC_SUFFIX = ".doc";

    /**
     * @Description: 導(dǎo)出word文件放在zip里面
     * @param zipName 壓縮包名稱
     * @param templateName 模板名稱,默認(rèn)取resources下的template文件夾
     * @param dataList 數(shù)據(jù)集合
     * @param clazz 數(shù)據(jù)類型
     * @param <T> 泛型
     */
    public static <T>void exportListFileOnZip(HttpServletResponse response, String zipName, String templateName, List<T> dataList,Class<T> clazz){
        //所有數(shù)據(jù)的輸出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 壓縮流
        ZipOutputStream zipOutputStream = null;
        try {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8") + ".zip");
            zipOutputStream = new ZipOutputStream(response.getOutputStream());
            Template template = getTemplate(templateName,clazz);
            Map<String,Integer> nameMap = new HashMap<>();
            for (T data : dataList) {
                String fileName = getFileName(data);
                if (nameMap.containsKey(fileName)) {
                    nameMap.put(fileName,nameMap.get(fileName) +1);
                    fileName = fileName+"(" + nameMap.get(fileName) +")";
                }else {
                    nameMap.put(fileName,0);
                }
                ByteArrayOutputStream byteArrayOutputStream = generateOneFile(template,data);
                outputStream.write(byteArrayOutputStream.toByteArray());
                ZipEntry zipEntry = new ZipEntry(fileName+DOC_SUFFIX);
                zipOutputStream.putNextEntry(zipEntry);
                zipOutputStream.write(byteArrayOutputStream.toByteArray());
                zipOutputStream.closeEntry();
            }
            zipOutputStream.write(outputStream.toByteArray());
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
            zipOutputStream.close();
        } catch (Exception e) {
            log.error("導(dǎo)出word文件放在zip里面異常",e);
        }finally {
            try {
                outputStream.close();
                zipOutputStream.close();
            } catch (IOException e) {
                log.error("導(dǎo)出word文件放在zip里面異常",e);
            }
        }
    }


    /**
     * @Description: 導(dǎo)出word文件所有數(shù)據(jù)都放在一個(gè)文件里面
     * @param fileName 文件名稱
     * @param templateName 模板名稱,默認(rèn)取resources下的template文件夾
     * @param dataList 數(shù)據(jù)集合
     * @param clazz 數(shù)據(jù)類型
     * @param <T> 泛型
     */
    public static <T> void exportListOnOneFile(HttpServletResponse response,String fileName,String templateName, List<T> dataList,Class<T> clazz){
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            response.setContentType("application/msword;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".doc");
            Template template = getTemplate(templateName,clazz);
            for (T data : dataList) {
                ByteArrayOutputStream byteArrayOutputStream = generateOneFile(template,data);
                outputStream.write(byteArrayOutputStream.toByteArray());
            }
            response.getOutputStream().write(outputStream.toByteArray());
            response.getOutputStream().flush();
            response.getOutputStream().close();
        } catch (Exception e) {
            log.error("導(dǎo)出word文件失敗",e);
        }finally {
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error("關(guān)閉流失敗",e);
            }
        }
    }

    /**
     * 導(dǎo)出提條數(shù)據(jù)放在一個(gè)word文件里面
     * @param response 響應(yīng)
     * @param fileName 文件名稱
     * @param templateName 模板名稱,默認(rèn)取resources下的template文件夾
     * @param data 數(shù)據(jù)
     * @param clazz 數(shù)據(jù)類型
     * @param <T> 泛型
     * @throws Exception 異常
     */
    public static <T> void exportOneFile(HttpServletResponse response, String fileName, String templateName, T data, Class<T> clazz) throws Exception{
        Template template = getTemplate(templateName,clazz);
        ByteArrayOutputStream outputStream = generateOneFile(template,data);
        response.setContentType("application/msword;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + ".doc");
        response.getOutputStream().write(outputStream.toByteArray());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }


    /**
     * 生成一個(gè)word文件的字節(jié)流
     * @param data 數(shù)據(jù)
     * @param <T> 泛型
     * @return 字節(jié)流
     * @throws Exception 異常
     */
    private static <T> ByteArrayOutputStream generateOneFile(Template template,T data) throws Exception{
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(outputStream);
        HashMap<String, Object> dataMap =  convertDataToHashMap(data);
        if (null == dataMap || dataMap.size() == 0) {
            log.error("數(shù)據(jù)為空");
            throw new RuntimeException("數(shù)據(jù)為空");
        }
        template.process(dataMap, writer);
        return outputStream;
    }

    /**
     * 轉(zhuǎn)換數(shù)據(jù)為hashMap供freemarker使用
     * @param data 數(shù)據(jù)
     * @param <T> 泛型
     * @return hashMap
     */
    private static <T>HashMap<String,Object> convertDataToHashMap(T data){
        //使用反射獲取類的屬性
        Class<?> myClass = data.getClass();
        Field[] fields = myClass.getDeclaredFields();
        HashMap<String,Object> dataMap = new HashMap<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ExportWordField.class)) {
                //允許訪問(wèn)私有變量
                field.setAccessible(true);
                //如果是list類型的數(shù)據(jù)需要深度遍歷處理
                if (field.getType().equals(List.class)) {
                    List<?> list = null;
                    try {
                        list = convertListDataToHashMap((List<?>) field.get(data));
                    } catch (IllegalAccessException e) {
                        log.error("獲取屬性值失敗",e);
                        throw new RuntimeException("獲取屬性值失敗");
                    }
                    dataMap.put(field.getName(),list);
                    continue;
                }
                ExportWordField exportWordField = field.getAnnotation(ExportWordField.class);
                String fieldName = exportWordField.fieldName();
                try {
                    if (fieldName != null && !"".equals(fieldName)) {
                        dataMap.put(fieldName,  field.get(data) == null ? "" : field.get(data));
                    }else {
                        dataMap.put(field.getName(), field.get(data) == null ? "" : field.get(data));
                    }
                } catch (IllegalAccessException e) {
                    log.error("獲取屬性值失敗",e);
                    throw new RuntimeException("獲取屬性值失敗");
                }
            }
        }
        return dataMap;
    }

    /**
     * 如果fidel是list類型的數(shù)據(jù)則需要判斷此層是否有l(wèi)ist類型的如果有需要不停的往底層變量一直到最后一層然后取每一層符合ExportWordField的數(shù)據(jù)返回給上一層
     * @param list list數(shù)據(jù)
     * @param <T> 泛型
     * @return hashMap
     */
    private static <T> List<HashMap<String, Object>> convertListDataToHashMap(List<T> list) {
        List<HashMap<String, Object>> listMap = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (T t : list) {
                HashMap<String, Object> hashMap = convertDataToHashMap(t);
                listMap.add(hashMap);
            }
        }
        return listMap;
    }

    /**
     * @Description: 讀取模板文件
     * @param templateName 模板名稱,默認(rèn)取resources下的template文件夾
     * @return freemarker.template.Template
     */
    private static <T>Template getTemplate(String templateName,Class<T> clazz) throws IOException {
        Configuration configuration = new Configuration(Configuration.getVersion());
        configuration.setDefaultEncoding("UTF-8");
        configuration.setClassForTemplateLoading(clazz, "/templates");
        return configuration.getTemplate(templateName);
    }
    
    private static <T> String getFileName(T data){
        Field[] fields = data.getClass().getDeclaredFields();
        StringBuilder fileName = new StringBuilder();
        Arrays.stream(fields).filter(field -> field.getAnnotation(ExportWordField.class) != null
                && field.getAnnotation(ExportWordField.class).isFileNameFiled()).sorted((o1, o2) -> {
            ExportWordField annotation1 = o1.getAnnotation(ExportWordField.class);
            ExportWordField annotation2 = o2.getAnnotation(ExportWordField.class);
            return annotation1.fileNameFiledSort() - annotation2.fileNameFiledSort();
        }).forEach(field -> {
            field.setAccessible(true);
            try {
                fileName.append(field.get(data)+"-");
            } catch (IllegalAccessException e) {
                log.error("獲取文件名稱異常",e);
            }
        });
        return fileName.toString();
    }
}

3.使用

  //導(dǎo)出壓縮包
  ExportTemplateUtil.exportListFileOnZip(response,"測(cè)試導(dǎo)出","template2.0.ftl",somethingObj,Something.class);
  //導(dǎo)出一個(gè)文件
  ExportTemplateUtil.exportOneFile(response,"測(cè)試導(dǎo)出","template2.0.ftl",somethingObj,Something.class);

文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-749631.html

到了這里,關(guān)于使用freemarker,導(dǎo)出制作好的ftl模板,并寫入數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • aspose 使用ftl模板生成word和pdf

    aspose 使用ftl模板生成word和pdf

    1 先找到word模板,用${},替換變量,保存,然后另存為xml,最后把xml后綴改成ftl。 如下圖: word 模板文件 ftl模板文件如下: 2 代碼生成 下面函數(shù)將ftl填充數(shù)據(jù),并生成word和pdf 3 測(cè)試主程序 4 結(jié)果: pdf文件 word文件 還可以生成圖片:

    2024年02月13日
    瀏覽(22)
  • ubuntu深度學(xué)習(xí)使用TensorFlow卷積神經(jīng)網(wǎng)絡(luò)——圖片數(shù)據(jù)集的制作以及制作好的數(shù)據(jù)集的使用

    ubuntu深度學(xué)習(xí)使用TensorFlow卷積神經(jīng)網(wǎng)絡(luò)——圖片數(shù)據(jù)集的制作以及制作好的數(shù)據(jù)集的使用

    首先我事先準(zhǔn)備好五分類的圖片放在對(duì)應(yīng)的文件夾,圖片資源在我的gitee文件夾中鏈接如下: 文件管理: 用于存各種數(shù)據(jù) https://gitee.com/xiaoxiaotai/file-management.git ?里面有imgs目錄和npy目錄,imgs就是存放5分類的圖片的目錄,里面有桂花、楓葉、五味子、銀杏、竹葉5種植物,npy目

    2024年02月05日
    瀏覽(91)
  • freemarker 使用word模板賦值

    freemarker 使用word模板賦值

    這里貼上自己測(cè)試的ftl文件 生成的效果 參考: https://blog.csdn.net/weixin_46174854/article/details/116855252 https://blog.csdn.net/weixin_45853881/article/details/129298494 https://blog.csdn.net/qq_42851623/article/details/122879852 https://blog.csdn.net/weixin_45103378/article/details/118395284 https://www.cnblogs.com/ayueC/p/15118381.html

    2024年02月11日
    瀏覽(20)
  • 若依框架中使用FreeMarker使用word動(dòng)態(tài)模板生成pdf給前端展示(模板中并沒(méi)用使用到圖片,所以沒(méi)有圖片的方法,只用了表格展示數(shù)據(jù),模板里面只涉及到了循環(huán)判斷和日期格式)

    若依框架中使用FreeMarker使用word動(dòng)態(tài)模板生成pdf給前端展示(模板中并沒(méi)用使用到圖片,所以沒(méi)有圖片的方法,只用了表格展示數(shù)據(jù),模板里面只涉及到了循環(huán)判斷和日期格式)

    首先使用word創(chuàng)建動(dòng)態(tài)模板 ?下方兩組信息是通過(guò)循環(huán)展示的,在生成模板時(shí)注意,如果不點(diǎn)擊里面表格,選擇居中表格打印出來(lái)可能還有偏差,兩邊距離頁(yè)面拒了可能不一樣 存儲(chǔ)需要的模板時(shí)注意 ? ? ?存成這個(gè)格式,如果不是2003可能會(huì)有坑,找到你生成的.xml文件,把后綴改成ftl ?

    2024年02月04日
    瀏覽(26)
  • freemarker模板引擎詳解以及使用方法

    freemarker模板引擎詳解以及使用方法

    哈嘍!大家好,我是曠世奇才李先生 文章持續(xù)更新,可以微信搜索【小奇JAVA面試】第一時(shí)間閱讀,回復(fù)【資料】更有我為大家準(zhǔn)備的福利喲,回復(fù)【項(xiàng)目】獲取我為大家準(zhǔn)備的項(xiàng)目 相關(guān)閱讀 面試官:Zookeeper是什么,它有什么特性與使用場(chǎng)景? 面試官:Redis如何實(shí)現(xiàn)持久化的

    2024年02月09日
    瀏覽(29)
  • Java使用ftl模板文件生成Word,以及Word轉(zhuǎn)換圖片或Pdf工具類

    Java使用ftl模板文件生成Word,以及Word轉(zhuǎn)換圖片或Pdf工具類

    一、寫在前面 最近在項(xiàng)目中使用打印功能,發(fā)現(xiàn)這個(gè)功能我已經(jīng)寫過(guò)多次了,下面這個(gè)文章的發(fā)步日期在2020年,不得不感慨時(shí)間之快啊。 https://blog.csdn.net/weixin_43238452/article/details/109636200?spm=1001.2014.3001.5501 下面介紹一下應(yīng)用場(chǎng)景:這次項(xiàng)目依舊是springboot項(xiàng)目,使用ftl模版生

    2024年02月15日
    瀏覽(38)
  • 根據(jù)模板動(dòng)態(tài)生成word(一)使用freemarker生成word

    根據(jù)模板動(dòng)態(tài)生成word(一)使用freemarker生成word

    @ 目錄 一、準(zhǔn)備模板 1、創(chuàng)建模板文件 2、處理模板 2.1 處理普通文本 2.2 處理表格 2.3 處理圖片 二、項(xiàng)目代碼 1、引入依賴 2、生成代碼 三、驗(yàn)證生成word 首先先建立一個(gè)word文件,輸入模板內(nèi)容freemaker的內(nèi)容,下面是本次演示的word文件。 然后將word文件另存為 .xml 文件,然后再

    2024年02月13日
    瀏覽(29)
  • freemarker模板在客服域的使用場(chǎng)景及用法介紹

    freemarker模板在客服域的使用場(chǎng)景及用法介紹

    ?? Java學(xué)習(xí):社區(qū)快速通道 ?? 深入淺出RocketMQ設(shè)計(jì)思想:深入淺出RocketMQ設(shè)計(jì)思想 ?? 絕對(duì)不一樣的職場(chǎng)干貨:大廠最佳實(shí)踐經(jīng)驗(yàn)指南 ?? 最近更新:2023年7月15日 ?? 點(diǎn)贊 ?? 收藏 ?留言 ?? 都是我最大的動(dòng)力! freemarker.template 是一個(gè)Java庫(kù),用于生成文本輸出(如HTML、X

    2024年02月16日
    瀏覽(16)
  • 使用easyexcel填充模板數(shù)據(jù),并導(dǎo)出excel

    使用easyexcel填充模板數(shù)據(jù),并導(dǎo)出excel

    導(dǎo)出excel功能非常場(chǎng)景,本片文章記錄如何使用模板填充數(shù)據(jù)后再導(dǎo)出。因直接導(dǎo)出excel數(shù)據(jù)樣式不符合要求,所以做了模板填充然后再導(dǎo)出excel。 效果如下: 注意:列表數(shù)據(jù)變量名前面要寫點(diǎn){.id},如果單條數(shù)據(jù)可以不寫。 使用表單提交: 實(shí)體代碼: controller代碼: 只對(duì)je

    2024年03月11日
    瀏覽(23)
  • Java根據(jù)模版導(dǎo)出(ftl方式)

    Java根據(jù)模版導(dǎo)出(ftl方式)

    實(shí)際項(xiàng)目中經(jīng)常遇到需要根據(jù)模版導(dǎo)出數(shù)據(jù),普通一點(diǎn)的導(dǎo)出模版都挺好實(shí)現(xiàn)的,如果涉及到勾選框、表格循環(huán)的方式就比較麻煩一點(diǎn),這篇文章主要記錄一下我在項(xiàng)目中是如何導(dǎo)出word(其中包括根據(jù)值勾選、表格循環(huán)、圖片) 一、先準(zhǔn)備一份word模版 如圖: 此模版主要是

    2024年02月07日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包