前后端交互過程中—各類文件/圖片的上傳、下載、顯示轉換

前后端交互過程中—各類文件/圖片的上傳、下載、顯示轉換

  • 圖片
    • 上傳下載常用函數:
      • new Blob()
          • **blobParts:(必傳)**
          • **options:(可選)**
          • blob的常見的MIME類型:
      • URL.createObjectURL()
      • 替代方案:FileReader.readAsDataURL()??
          • FileReader 提供了幾種方法來讀取文件,
      • 對比:
    • 獲取tiff文件 轉 png
      • TIFF庫
      • TIFF轉換
        • 通過url轉換tiff文件為png
        • 通過文件選擇的方式轉換tiff文件為png
    • 下載(導出)
    • 普通圖片文件png,jpg,jpeg,gif

圖片

上傳下載常用函數:

new Blob()

Blob常用于處理二進制數據,比如讀取文件內容創建文件下載鏈接

const blob = new Blob(blobParts, options);
blobParts:(必傳)

必須是一個??數組??,其中包含以下任意組合:
在這里插入圖片描述

options:(可選)

包含以下可選屬性的對象:
在這里插入圖片描述

blob的常見的MIME類型:
類型子類型典型文件擴展名用途示例
textplain.txt純文本文件
html.html, .htmHTML文檔
css.css層疊樣式表
csv.csv逗號分隔值文件
javascript.jsJavaScript文件
imagejpeg.jpegJPEG圖像
png.pngPNG圖像
gif.gifGIF圖像
svg+xml.svgSVG矢量圖形
webp.webpWebP圖像
audiompeg.mp3MP3音頻
ogg.oggOGG音頻
wav.wavWAV音頻
webm.webmWebM音頻
videomp4.mp4MP4視頻
ogg.ogvOGG視頻
webm.webmWebM視頻
applicationoctet-stream任意任意二進制數據(默認)
json.jsonJSON數據
xml.xmlXML數據
pdf.pdfPDF文檔
zip.zipZIP壓縮文件
vnd.ms-excel.xlsExcel 97-2003 工作簿
vnd.openxmlformats-officedocument.spreadsheetml.sheet.xlsxExcel 工作簿(2007+)
msword.docWord 97-2003 文檔
vnd.openxmlformats-officedocument.wordprocessingml.document.docxWord 文檔(2007+)

示例:

// 創建文本Blob
const textBlob = new Blob(["Hello, world!"], {type: "text/plain"});// 創建JSON Blob
const data = {name: "Alice", age: 30};
const jsonBlob = new Blob([JSON.stringify(data)], {type: "application/json"});// 示例:默認類型(二進制流)
const defaultBlob = new Blob([anyData]); // 默認類型為 "application/octet-stream"// 創建圖像Blob(偽代碼)
const canvas = document.createElement('canvas');
// ... 在canvas上繪制 ...
canvas.toBlob((blob) => {// blob已準備好使用
}, "image/png");// 組合字符串、ArrayBuffer和現有Blob
const header = "FILE HEADER\n";
const binaryData = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello"
const existingBlob = new Blob([" World!"], {type: "text/plain"});const combinedBlob = new Blob([header, binaryData, existingBlob], {type: "text/plain"}
);

URL.createObjectURL()

URL.createObjectURL() 是 Web API 中的一個方法,它可以將一個 Blob ——(二進制數據對象)File ——用戶文件(繼承自 Blob)MediaSource——(流媒體場景)對象轉換為一個唯一的 URL

這個 URL 的生命周期與創建它的文檔綁定,并且通常用于在瀏覽器中臨時引用一個本地文件二進制數據

基本用法:

  • const objectURL = URL.createObjectURL(blob);
    blob:一個 Blob、File 或 MediaSource 對象。
    返回值:一個字符串,表示一個指向該對象的臨時 URL。(格式為 blob:origin/unique-id)

內存管理?? :生成的 URL 會一直存在于內存中,直到文檔被卸載(頁面關閉)或手動撤銷(URL.revokeObjectURL(objectURL))。

??URL 的生命周期??:這個 URL 只在當前文檔(document)中有效。如果導航到其他頁面,這個 URL 就會失效。

??安全性??:生成的 URL 是 blob: 協議,其內容只能由創建它的頁面訪問,具有一定的安全性。

應用場景

  • 預覽用戶選擇(上傳時)的圖片??:
    當用戶通過 < input type=“file” > 選擇圖片后,可以用 createObjectURL 生成一個 URL 并賦給 < img > 的 src,從而在不將圖片上傳到服務器的情況下預覽圖片。
<input type="file" id="upload" accept="image/*">
<img id="preview" src="#" alt="預覽">
		const upload = document.getElementById('upload');const preview = document.getElementById('preview');upload.addEventListener('change', function(e) {const file = e.target.files[0];if (file) {// 為選中的文件創建臨時URLconst objectURL = URL.createObjectURL(file);// 將img標簽的src指向這個URLpreview.src = objectURL;// 在圖片加載后(或者合適的時機)撤銷URL,這里我們等待圖片加載完成preview.onload = function() {URL.revokeObjectURL(objectURL);};}});
  • 處理(下載)二進制數據??:
    例如,下載由 JavaScript 生成的二進制數據(如 PDF、圖片等),或在不使用服務器的情況下在頁面中顯示這些數據。

    	// 創建blob對象// 1.const response = await fetch('http://XXX');const blob = await response .blob();// 2.valueconst value= "Hello, world!";const blob2 = new Blob([value], {type: "text/plain"}); // image/png// 創建URL對象const url = URL.createObjectURL(blob);// 創建a標簽......點擊下載const a = document.createElement('a');a.href = url;a.download = 'example.txt';   // 設置下載文件名a.click();   // 觸發下載setTimeout(() => URL.revokeObjectURL(url), 100);// 立即釋放資源(不需要等待下載)
  • ??處理音視頻流??:(播放用戶上傳的視頻)
    在 WebRTC 或媒體處理中,用于創建指向媒體流的 URL。

    	<input type="file" accept="video/*" id="video-upload"><video controls id="player"></video><script>document.getElementById('video-upload').addEventListener('change', (e) => {const file = e.target.files[0];if (file) {const video = document.getElementById('player');video.src = URL.createObjectURL(file);video.onload = () => URL.revokeObjectURL(video.src); // 清理}});</script>
    

替代方案:FileReader.readAsDataURL()??

將文件轉為 Base64 字符串(格式 data:[mime];base64,…),但??不適合大文件??(內存占用更高)。

有時候,我們也可以用 FileReader 來讀取文件內容,例如:

const reader = new FileReader();
reader.onload = function(e) {preview.src = e.target.result;
};
reader.readAsDataURL(file);

readAsDataURL 會生成一個 Data URL(以 data: 開頭的字符串),它包含了文件的全部內容(base64編碼)。
這種方式不需要手動撤銷URL,但文件較大時可能會占用更多內存。

FileReader 提供了幾種方法來讀取文件,

每種方法適用于不同的文件類型或讀取方式:

readAsText(file, [encoding])
以文本形式讀取文件內容。
第二個參數是可選的,指定文本編碼(如 UTF-8)。
readAsDataURL(file)
將文件讀取為 Data URL,通常用于將圖像文件嵌入到網頁中。
readAsArrayBuffer(file)
將文件讀取為 ArrayBuffer,適合處理二進制數據,如音頻、視頻或圖像。
readAsBinaryString(file)(已廢棄)
將文件讀取為二進制字符串。不推薦使用,建議使用 ArrayBuffer 替代。

對比:

在這里插入圖片描述

獲取tiff文件 轉 png

說明:
由于tiff格式在瀏覽器中并不常見,且瀏覽器默認不支持直接顯示tiff圖片。
tiff文件在前端中不可以直接通過image標簽顯示,
因此我們需要借助第三方庫來將tiff文件轉換成png。

TIFF庫

utif:一個輕量級的TIFF解析庫
tiff.js:一個將TIFF圖像轉換為可顯示格式的庫

utif庫輕量且簡單,以下以utif庫使用為例:

  • 安裝:
npm install utifnpm install tiff.js
  • 使用:
import * as UTIF from 'utif';import { Tiff } from 'tiff.js';

注意:由于utif庫處理的是TIFF文件的二進制數據,我們需要使用FileReader來讀取文件。

  • 注意事項:
  1. 大文件處理??:
    大尺寸 TIFF 文件可能導致內存問題
    考慮添加文件大小限制和加載提示
  2. 服務器端替代方案??:
    // 替代方案:使用服務器轉換(如Node.js+Sharp)
    async serverConversion(file) {const formData = new FormData();formData.append('tiff', file);const response = await fetch('/api/convert', {method: 'POST',body: formData});return URL.createObjectURL(await response.blob());
    }
    
  3. 瀏覽器兼容性??:
    所有現代瀏覽器均支持
    IE11 需要 polyfill(推薦使用現代瀏覽器)
  4. 安全性??:
    上傳時驗證文件頭確保是真實TIFF文件:
    const isValidTiff = buffer[0] === 0x49 && buffer[1] === 0x49;
    

此實現完全在客戶端完成轉換,無需服務器支持,適合中小型TIFF文件的轉換需求。對于專業級應用(如醫學影像),建議使用服務器端解決方案(如Python+pillow
或 Node.js+sharp)。

TIFF轉換

通過url轉換tiff文件為png
  1. 獲取在線的TIFF文件(通常是一個URL)??:使用 Fetch API 獲取遠程 TIFF 文件的 ArrayBuffer
  2. 解析TIFF??:使用 如tiff.js 庫解析二進制數據,獲取圖像信息
  3. 將圖像數據繪制到canvas上,Canvas轉換??:
    創建臨時 Canvas 元素
    使用 toRGBA8() 方法獲取像素數據
    通過 putImageData 繪制到 Canvas
  4. 轉換為PNG??,使用canvas的toDataURL方法將其轉換為PNG格式的數據URL:
    使用 canvas.toDataURL(‘image/png’) 獲取 PNG 數據 URL
  5. ??顯示和下載??:
    通過 img 標簽展示
    創建下載鏈接實現PNG下載

// 引入依賴
import * as UTIF from "utif";
// tiff文件URL轉換_方法封裝
const tiffUrlToPng = async (fileUrl) => {if (!fileUrl) {console.log("請輸入TIFF文件URL");return;}// 自定義初始化工作let result = "";// this.isLoading = true;// this.error = null;// this.pngImage = null;// 使用 Fetch API 獲取遠程 TIFF 文件的 ArrayBufferawait fetch(fileUrl).then((response) => {if (!response.ok) {throw new Error("Network response was not ok");}return response.arrayBuffer();}).then((buffer) => {// 解析tiff數據const uint8Array = new Uint8Array(buffer);const ifds = UTIF.decode(uint8Array);// 獲取第一幀(支持多幀TIFF)const firstPage = ifds[0];UTIF.decodeImage(uint8Array, ifds[0]);const rgba = UTIF.toRGBA8(firstPage);// 創建Canvasconst canvas = document.createElement("canvas");canvas.width = firstPage.width;canvas.height = firstPage.height;const ctx = canvas.getContext("2d");// 將圖像數據放入Canvasconst imageData = new ImageData(new Uint8ClampedArray(rgba),canvas.width,canvas.height);ctx.putImageData(imageData, 0, 0);// 轉換為PNG Data URL// resolve(canvas.toDataURL("image/png"));result = canvas.toDataURL("image/png");}).catch((error) => {console.error("Error:", error); // 處理錯誤});return result; //返回為promise對象。使用.then()方法獲取結果。
};

utff.js使用(通過URL獲取tiff文件轉換)

<template><div><input type="text" v-model="tiffUrl" placeholder="輸入TIFF文件URL"><button @click="convertToPng" :disabled="isLoading">轉換為PNG</button><div v-if="isLoading">轉換中...</div><img v-if="pngImage" :src="pngImage" alt="轉換后的PNG" style="max-width: 100%"><div v-if="error" class="error">{{ error }}</div><button v-if="pngImage" @click="downloadPng">下載PNG</button></div>
</template><script>
import { Tiff } from 'tiff.js';export default {data() {return {tiffUrl: '',      // 存儲輸入的TIFF URLpngImage: null,   // 轉換后的PNG數據URLisLoading: false, // 加載狀態error: null       // 錯誤信息};},methods: {async convertToPng() {if (!this.tiffUrl) {this.error = '請輸入TIFF文件URL';return;}this.isLoading = true;this.error = null;this.pngImage = null;try {// 1. 獲取TIFF文件數據const response = await fetch(this.tiffUrl);if (!response.ok) throw new Error(`文件加載失敗: ${response.status}`);const buffer = await response.arrayBuffer();// 2. 解析TIFFconst tiff = new Tiff({ buffer });const width = tiff.width();const height = tiff.height();// 3. 使用Canvas轉換const canvas = document.createElement('canvas');canvas.width = width;canvas.height = height;const ctx = canvas.getContext('2d');// 獲取TIFF像素數據并繪制到Canvasconst imageData = ctx.createImageData(width, height);imageData.data.set(tiff.toRGBA8()); // 轉換為RGBA格式ctx.putImageData(imageData, 0, 0);// 4. 轉換為PNGthis.pngImage = canvas.toDataURL('image/png');} catch (err) {console.error('轉換失敗:', err);this.error = `轉換失敗: ${err.message || '未知錯誤'}`;} finally {this.isLoading = false;}},// 下載轉換后的PNGdownloadPng() {if (!this.pngImage) return;const link = document.createElement('a');link.href = this.pngImage;link.download = 'converted_image.png';document.body.appendChild(link);link.click();document.body.removeChild(link);}}
};
</script><style>
.error {color: red;margin-top: 10px;
}
</style>
通過文件選擇的方式轉換tiff文件為png

實現說明:
??

  1. 文件選擇??:
    • 使用 接受用戶上傳的 TIFF 文件
    • 設置 accept=“.tif,.tiff” 限制文件類型
  2. ??TIFF 轉換核心流程??:
    • 使用 FileReader 讀取文件為 ArrayBuffer;
    • 通過 UTIF.decode() 解析 TIFF 文件結構;
    • 使用 UTIF.toRGBA8() 將 TIFF 轉換為 RGBA 格式;
    • 使用 Canvas 將圖像數據渲染為 PNG
  3. 多幀支持??:
    • ifds 數組包含 TIFF 的所有幀;
    • ifds[0] 獲取第一幀(可根據需要循環處理多幀)
  4. ??下載功能??:
    • 將 Canvas 生成的 Data URL 轉換為可下載鏈接;
    • 通過動態創建 a 標簽觸發下載
<template><div><input type="file" @change="handleFileUpload" accept=".tif,.tiff"><div v-if="previewUrl"><img :src="previewUrl" alt="Converted PNG" style="max-width: 100%"><button @click="downloadPNG">下載PNG</button></div></div>
</template><script>
import * as UTIF from 'utif';export default {data() {return {previewUrl: null,convertedImage: null};},methods: {async handleFileUpload(event) {const file = event.target.files[0];if (!file) return;try {const pngDataUrl = await this.convertTiffToPng(file);this.previewUrl = pngDataUrl;} catch (error) {console.error('轉換失敗:', error);alert('文件轉換失敗,請確保是有效的TIFF文件');}},async convertTiffToPng(tiffFile) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = (e) => {try {// 解析TIFF數據const buffer = new Uint8Array(e.target.result);const ifds = UTIF.decode(buffer);UTIF.decodeImages(buffer, ifds);// 獲取第一幀(支持多幀TIFF)const firstPage = ifds[0];const rgba = UTIF.toRGBA8(firstPage);// 創建Canvasconst canvas = document.createElement('canvas');canvas.width = firstPage.width;canvas.height = firstPage.height;const ctx = canvas.getContext('2d');// 將圖像數據放入Canvasconst imageData = new ImageData(new Uint8ClampedArray(rgba),canvas.width,canvas.height);ctx.putImageData(imageData, 0, 0);// 轉換為PNG Data URLresolve(canvas.toDataURL('image/png'));} catch (err) {reject(err);}};reader.onerror = reject;reader.readAsArrayBuffer(tiffFile);});},downloadPNG() {if (!this.previewUrl) return;const link = document.createElement('a');link.href = this.previewUrl;link.download = 'converted_image.png';document.body.appendChild(link);link.click();document.body.removeChild(link);}}
};
</script>

下載(導出)

function downloadFile(blob, fileName) {const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = fileName;document.body.appendChild(a);a.click();// 清理setTimeout(() => {document.body.removeChild(a);URL.revokeObjectURL(url);}, 100);
}

普通圖片文件png,jpg,jpeg,gif

上傳下載如上代碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83210.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83210.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83210.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

校園二手交易平臺(微信小程序版)

文章目錄 1. 項目概述2. 項目功能思維導圖3. 技術架構1. 前端技術棧2. 后端技術棧 4. 核心模塊實現5. 總結6. 項目實現效果截圖7. 關于作者其它項目視頻教程介紹 1. 項目概述 校園二手交易平臺微信小程序旨在為在校學生提供一個便捷的二手物品交易渠道&#xff0c;包含用戶模塊…

Linux簡單的操作

ls ls 查看當前目錄 ll 查看詳細內容 ls -a 查看所有的內容 ls --help 查看方法文檔 pwd pwd 查看當前路徑 cd cd 轉路徑 cd .. 轉上一級路徑 cd 名 轉換路徑 …

【芯片設計- RTL 數字邏輯設計入門 4.2 -- 組合邏輯賦值 + 時序邏輯狀態保持】

文章目錄 Overview原語句分析變量含義假設(根據命名推測)狀態更新邏輯詳解狀態轉移邏輯舉個實際例子小結Overview 本文將詳細介紹 verilog rtl 中 assign reg_halt_mode_nx = halt_taken | (reg_halt_mode & ~halt_return);的作用,以及這里為何要使用 reg_halt_mode,…

【單片機期末】匯編試卷

一、選擇題 DPTR是16位的&#xff0c;所以尋址范圍是64KB R1是8位的&#xff0c;只能尋址256 訪問內部ROM只能用MOVC指令 一個指令周期是時鐘周期的1/12 12個時鐘周期是一個機器周期 單指令周期是指一個機器周期 T 1 / f 12MHz ~ 1us 13位計數16位計數8位自動重裝載雙8位計數器…

校驗枚舉類類型的入參合法性的統一方案

文章目錄 背景解決實踐定義枚舉類 InEnum注解定義驗證邏輯 InEnumValidator 實際使用 背景 業務要做電商平臺做入參, 在電商平臺被抽離成枚舉類的情況下 &#xff0c;要怎么驗證輸入的參數是正確的呢? 解決 Constraint 實現自定義驗證邏輯 Constraint 注解用于標注其他注解&am…

Unity-NavMesh詳解-其一

今天我們來詳細地探究一下Unity的NavMesh這一性能強大的組件&#xff1a; NavMesh基本使用 NavMesh簡單地說本質上是一個自動尋路的AI組件&#xff0c;我們首先來學習基本的使用。 畫面中我已經添加好了地面&#xff0c;目標&#xff0c;障礙物以及玩家四個要素。 注意我們要…

vue的created和mounted區別

在Vue.js中&#xff0c;created和mounted的核心區別在于調用時機和DOM可訪問性?&#xff1a;created鉤子在組件實例創建后、DOM掛載前調用&#xff0c;適用于數據初始化&#xff1b;mounted鉤子在DOM掛載后調用&#xff0c;支持DOM操作。?? ?調用時機與核心能力對比? ?…

MySQL 8.0 OCP 英文題庫解析(十四)

Oracle 為慶祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免費考取原價245美元的MySQL OCP 認證。 從今天開始&#xff0c;將英文題庫免費公布出來&#xff0c;并進行解析&#xff0c;幫助大家在一個月之內輕松通過OCP認證。 本期公布試題121~130 試題1…

【HarmonyOS 5】拍攝美化開發實踐介紹以及詳細案例

以下是 HarmonyOS 5 拍攝美化功能的簡潔介紹&#xff0c;整合核心能力與技術亮點&#xff1a; 一、AI 影像創新 ?AI 魔法移圖? 系統級圖像分層技術實現人物/物體自由拖拽、縮放與復制&#xff0c;突破傳統構圖限制。自動分離主體與背景&#xff0c;一鍵生成錯位創意照&…

【Java多線程從青銅到王者】懶漢模式的優化(九)

懶漢模式的問題 我們看上述的代碼&#xff0c;當第一次調用getIntance的時候&#xff0c;intance為null&#xff0c;就會進入if里面&#xff0c;創建出實例&#xff0c;當不是第一次調用的時候&#xff0c;此時的intandce不是null&#xff0c;不進入循環&#xff0c;直接return…

SCI期刊查重參考文獻會被查重嗎?

查重的時候&#xff0c;參考文獻不會被查重。 不管中文還是英文查重系統里一般都有排除參考文獻的設置。 比如英文查重系統iThenticate 的排除文獻的設置如下&#xff1a; 在iThenticate在線報告界面的右下角點擊“漏斗”圖標&#xff08;Filter&#xff09;&#xff0c; ?…

OpenLayers 獲取地圖狀態

注&#xff1a;當前使用的是 ol 5.3.0 版本&#xff0c;天地圖使用的key請到天地圖官網申請&#xff0c;并替換為自己的key 地圖狀態信息包括中心點、當前縮放級別、比例尺以及當前鼠標移動位置信息等&#xff0c;在WebGIS開發中&#xff0c;地圖狀態可以方便快捷的向用戶展示基…

JxBrowser 8.8.0 版本發布啦!

一次調用即可下載文件精準清除瀏覽數據右鍵點擊位置檢測獲取元素在視口中的位置 &#x1f517; 點擊此處了解更多詳情。 &#x1f193; 獲取 30 天免費試用。

React 中的TypeScript開發范式

在 TypeScript 中使用 React 可以提高代碼的可維護性、可讀性和可靠性。TypeScript 提供了靜態類型檢查和豐富的類型系統&#xff0c;這些功能在 React 開發中非常有用。下面詳細介紹如何在 React 項目中使用 TypeScript&#xff0c;并結合泛型和 infer 來定義類型。 1. 項目初…

72道Nginx高頻題整理(附答案背誦版)

1. 簡述什么是Nginx &#xff1f; Nginx 是一個開源的高性能HTTP和反向代理服務器&#xff0c;也能夠用作IMAP/POP3/SMTP代理服務器。它最初由Igor Sysoev為俄羅斯的一個大型網站Rambler開發&#xff0c;并在2004年首次公開發布。Nginx被設計用來解決C10k問題&#xff0c;即同…

AI時代,數據分析師如何成為不可替代的個體

在數據爆炸的 AI 時代&#xff0c;AI工具正以驚人的速度重塑數據分析行業&#xff0c;數據分析師的工作方式正在經歷一場前所未有的變革。數據分析師又該如何破局&#xff0c;讓自己不被AI取代呢&#xff1f; 一、AI工具對重復性工作的徹底解構 如以往我們需要花幾天寫一份數…

DockerHub與私有鏡像倉庫在容器化中的應用與管理

哈嘍&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的應用與管理 Docker Hub的基本概念與使用方法 Docker Hub是Docker官方提供的一個公共鏡像倉庫&#xff0c;用戶可以在其中找到各種操作系統、軟件和應用的鏡像。開發者可以通過Docker Hub輕松獲取所…

Kafka入門-Broker以及文件存儲機制

Kafka Broker Broker實際上就是kafka實例&#xff0c;每一個節點都是獨立的Kafka服務器。 Zookeeper中存儲的Kafka信息 節點的服役以及退役 服役 首先要重新建立一臺全新的服務器105&#xff0c;并且在服務器中安裝JDK、Zookeeper、以及Kafka。配置好基礎的信息之后&#x…

dexcap升級版之DexWild——面向戶外環境的靈巧手交互策略:人類和機器人演示協同訓練(人類直接帶上動捕手套采集數據)

前言 截止到25年6.6日&#xff0c;在沒動我司『七月在線』南京、武漢團隊的機器的前提下&#xff0c;長沙這邊所需的前幾個開發設備都已到齊——機械臂、宇樹g1 edu、VR、吊架 ?長沙團隊必須盡快追上南京步伐 加速前進 如上篇文章所說的&#xff0c; 為盡快 讓近期新招的新同…

【基于阿里云搭建數據倉庫(離線)】使用UDTF時出現報錯“FlatEventUDTF cannot be resolved”

目錄 問題&#xff1a; 可能的原因有&#xff1a; 解決方法&#xff1a; 問題&#xff1a; 已經將包含第三方依賴的jar包上傳到dataworks&#xff0c;并且成功注冊函數&#xff0c;但是還是報錯&#xff1a;“FlatEventUDTF cannot be resolved”&#xff0c;如下&#xff1a…