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
    • 創建新的單詞集...
  • 拷貝


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM