• js将文件流转为文件


    js将文件流转为文件

    需求:

    前端通过ajax请求后端,根据接收前端的参数生成相应的文件,并将文件返回到前端提供下载。

    方案1:

    通过ajax请求后端,将生成的文件直接通过response.write的方式直接将生成的文返回。
    该方案失败,由于ajax请求返回的数据需要在回调函数中获取,返回的data没法直接转为文件下载。

    方案2:

    通过ajax请求后端,将生成的文件转为文件字符流返回到前端,前端使用Blob的方式将文件字符流数据写入文件,再下载。

    具体实现代码如下

    • 后端代码
    1. 文件生成使用freemarker模版引擎
        /**
         * 
         * @param dataMap
         *            word中需要展示的动态数据
         * @param templateName
         *            word模板名称 eg:test.ftl
         * @param filePath
         *            文件生成的目标路径,eg:D:/wordFile/
         * @param fileName
         *            生成的文件名称,eg:test.doc
         */
        public File createWord(Map<String, Object> dataMap, String templateName, String filePath, String fileName) {
            // 输出文件
            File outFile = null;
            try {
                // 创建配置实例
                Configuration configuration = new Configuration();
    
                // 设置编码
                configuration.setDefaultEncoding(encode);
    
                // ftl模板文件统一放至 com.lun.template 包下面
                configuration.setClassForTemplateLoading(FreemarkService.class, templatePath);
                
                //设置错误显示方式
                configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
                
                // 设置对象包装器
                configuration.setObjectWrapper(new DefaultObjectWrapper());
                
                //处理空值
                configuration.setClassicCompatible(true);
                
                // 获取模板
                Template template = configuration.getTemplate(templateName);
    
                // 输出文件
                outFile = new File(filePath + File.separator + fileName);
    
                // 如果输出目标文件夹不存在,则创建
                if (!outFile.getParentFile().exists()) {
                    outFile.getParentFile().mkdirs();
                }
    
                // 将模板和数据模型合并生成文件
                Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), encode));
    
                // 生成文件
                template.process(dataMap, out);
    
                // 关闭流
                out.flush();
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return outFile;
        }
    1. 将生成的文件调用FileUtils工具类将文件转为字节流数据
            byte[] fileBuff = null;
            try {
                fileBuff = FileUtils.readFileToByteArray(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
    1. 将字节流数据转为字符流数据
        /**
         * 字节流转字符流
         * @param bytes
         * @return
         */
        private char[] getChars(byte[] bytes) {
            Charset cs = Charset.forName("UTF-8");
            ByteBuffer bb = ByteBuffer.allocate(bytes.length);
            bb.put(bytes).flip();
            CharBuffer cb = cs.decode(bb);
            return cb.array();
        }

    以上完成将文件转为字符流后,可以直接返回到前端。

    • 前端代码
    
            // 下载文件方法 
            var downloadDoc = function(content, filename) { 
                var eleLink = document.createElement('a'); 
                eleLink.download = filename; 
                eleLink.style.display = 'none'; 
                // 字符内容转变成blob地址 
                var blob = new Blob([content]); 
                eleLink.href = URL.createObjectURL(blob); 
                // 自动触发点击 
                document.body.appendChild(eleLink); 
                eleLink.click(); 
                // 然后移除 
                document.body.removeChild(eleLink); 
            }; 

    @content:后端返回的文件字符流数据
    @filename:下载时显示的默认文件名
    在ajax请求的回调函数中调用该方法即可触发文件下载的操作事件。

    bolb介绍

     

    二次优化(兼容IE11):

    后端优化改进为返回base64字符串:

    return Base64.encodeBase64String(fileBuff);

    前端调整:

    js中base64字符串转Uint8Array

    // 下载文件方法 
    var downloadDoc = function(fileData, filename) { 
        var content = base64ToUint8Array(fileData);
        var blob = new Blob([content]); 
        if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(blob, filename);
        } else {
            var a = document.createElement('a');
            var url = window.URL.createObjectURL(blob);
            if (!url) {
                url = window.webkitURL.createObjectURL(blob);
            }
            a.href = url;
            a.download = filename;
            a.click();
            window.URL.revokeObjectURL(url);
        }
    }; 
            
    //base64字符串转array
    var base64ToUint8Array = function(base64String) {
        var rawData = window.atob(base64String);
        var len = rawData.length;
        var buffer = new ArrayBuffer(len);
        var outputArray = new Uint8Array(buffer);
        while (--len) {
            outputArray[len] = rawData.charCodeAt(len);
        }
        return outputArray;
    }

    参考:兼容IE浏览器

    • 添加到短语集
       
      • history
      • 创建新的单词集...
    • 拷贝
    初心回归,时光已逝!
  • 相关阅读:
    我的2020书单
    记录一次克隆硬盘的经历
    npm简单介绍
    批量处理Excel从格式xls到xlsx
    SQL经典实例笔记
    在字符串中找出连续最长的数字串
    将数字转化成字符串
    寄存器位读写,结构体位域定义,位域操作,位操作
    android C/C++ source files 全局宏定义 .
    android2.3 -添加自定义按键:作唤醒功能 .
  • 原文地址:https://www.cnblogs.com/yin1361866686/p/11572920.html
Copyright © 2020-2023  润新知