主要介紹兩種方式實(shí)現(xiàn)文件預(yù)覽的方式,一種是通過(guò)前端插件匹配不同的文件,另一種就是使用已經(jīng)完善的文件預(yù)覽系統(tǒng)。我更推薦使用第二種方式,因?yàn)檫@樣會(huì)少去很多工作量。本文主要介紹第一種方式,第二種方式會(huì)出現(xiàn)在另外一篇文章中。
本文是基于若依前后端分離版本實(shí)現(xiàn)文件預(yù)覽功能。若依官網(wǎng)鏈接。
通過(guò)前端插件匹配文件預(yù)覽:有兩個(gè)思路,一個(gè)是傳blob流,然后將流轉(zhuǎn)成對(duì)應(yīng)的文件格式,再進(jìn)行預(yù)覽。另一個(gè)是通過(guò)后端將文件地址映射出來(lái),然后通過(guò)瀏覽器進(jìn)行訪問(wèn)。兩種方式各有優(yōu)缺點(diǎn),blob流方式在進(jìn)行本地測(cè)試階段,沒(méi)有發(fā)現(xiàn)任何問(wèn)題,但是當(dāng)部署到服務(wù)器,就會(huì)出現(xiàn)文件流傳輸速度問(wèn)題,如果是內(nèi)網(wǎng)使用,速度還可以接收,但是外網(wǎng)使用,預(yù)覽速度根本無(wú)法接收。blob流方式預(yù)覽就相當(dāng)于下載完文件后,再進(jìn)行預(yù)覽,所以速度很慢。瀏覽器打開(kāi)方式只支持瀏覽器支持預(yù)覽的文件,很多文件格式不支持。總之,這兩種文件預(yù)覽方式的缺陷還是很大的,如果文件預(yù)覽支持的格式較少,文件都不是很大,適用于個(gè)人學(xué)習(xí),只使用電腦端使用而不使用手機(jī)端時(shí),可以進(jìn)行使用。
1.文件操作的時(shí)間比簡(jiǎn)單調(diào)用數(shù)據(jù)庫(kù)的時(shí)間長(zhǎng)很多。為了避免前端訪問(wèn)后端接口因?yàn)槌卸鴪?bào)錯(cuò),將超時(shí)時(shí)間設(shè)置長(zhǎng)一點(diǎn)。將ruoyi-ui/src/utils/request.js文件下的timeout設(shè)置為6000000,可以根據(jù)自己的使用情況進(jìn)行設(shè)置。
// 創(chuàng)建axios實(shí)例
const service = axios.create({
// axios中請(qǐng)求配置有baseURL選項(xiàng),表示請(qǐng)求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超時(shí)
timeout: 6000000
})
2.文件預(yù)覽之前,先要進(jìn)行文件上傳。文件上傳的內(nèi)容可以看我寫(xiě)的《SpringBoot實(shí)現(xiàn)文件上傳和下載》。后端在ruoyi-admin/src/main/resources/application.yml文件最后面添加文件路徑配置,文件地址可以自行設(shè)置。
prop:
filePath: d:/csdn/onlineFile/
3.后端返回文件流的接口,其中filePath是在controller類中通過(guò)@Value導(dǎo)入。
@Value("${prop.filePath}")
private String filePath;
/**
* 根據(jù)文件名下載文件
*
* @param fileName 文件名,是由文件id+文件擴(kuò)展名(extName)組成
* @return 文件信息
* @throws IOException
*/
@GetMapping("/download")
public ResponseEntity<InputStreamResource> download(String fileName) throws IOException {
String path = filePath + fileName;
FileSystemResource file = new FileSystemResource(path);
// 設(shè)置響應(yīng)頭
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
return ResponseEntity
.ok()
.headers(headers)
.contentLength(file.contentLength())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(file.getInputStream()));
}
4.在ruoyi-ui/src/api下面創(chuàng)建文件夾file,在此文件夾下創(chuàng)建file.js文件,用于訪問(wèn)與文件有關(guān)的后端接口。
import request from "@/utils/request";
let fileUrl = '后端controller的RequestMapping的值'
export function getPrevieweFile(fileName) {
return request({
url: fileUrl + '/download',
method: 'get',
params: {
fileName
},
responseType: 'blob'
})
}
注意:
1.url為后端controller的RequestMapping的值+RequestMapping的值。
2.返回類型必須設(shè)置為blob。
5.blob值的獲取方式。
getPrevieweFile(fileName).then(res => {
let blob = new Blob([res]);
//通過(guò)switch,調(diào)用不同類型文件的處理函數(shù)
switch (file.extName) {
case '.txt':
this.previewData.type = 'txt';
this.handleTxtFilePreview(blob);
break;
case '.png':
this.previewData.type = 'image';
this.handleImageFilePreview(blob);
break;
case '.jpg':
this.previewData.type = 'image';
this.handleImageFilePreview(blob);
break;
case '.xls':
this.previewData.type = 'excel';
this.handleExcelFilePreview(blob);
break;
case '.xlsx':
this.previewData.type = 'excel';
this.handleExcelFilePreview(blob);
break;
case '.docx':
this.previewData.type = 'word';
this.handleWrodFilePreview(blob);
break;
case '.pdf':
this.previewData.type = 'pdf';
this.handlePdfFilePreview(blob);
break;
}
})
6.blob流方式的.txt文件
handleTxtFilePreview(blob) {
let reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = (evt) => {
let ints = new Uint8Array(evt.target.result); //要使用讀取的內(nèi)容,所以將讀取內(nèi)容轉(zhuǎn)化成Uint8Array
ints = ints.slice(0, blob.size); //截取一段讀取的內(nèi)容
let text = new TextDecoder('utf-8').decode(ints); //二進(jìn)制緩存區(qū)內(nèi)容轉(zhuǎn)化成中文(即也就是讀取到的內(nèi)容)
console.log(text);
};
}
提示:text中的內(nèi)容就是轉(zhuǎn)換出來(lái)的內(nèi)容,具體怎么顯示可根據(jù)實(shí)際情況而定。
結(jié)果:
控制臺(tái)打印
顯示
7.blob流方式的.png和.jpg文件
handleImageFilePreview(blob) {
let url = URL.createObjectURL(blob);
}
提示:url就是圖片地址,可以通過(guò)img標(biāo)簽,然后將src的值傳入url,就可以查看圖片。
結(jié)果:
8.blob流方式的.xls和.xlsx文件
handleExcelFilePreview(blob) {
let reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = (evt) => {
let ints = new Uint8Array(evt.target.result); //要使用讀取的內(nèi)容,所以將讀取內(nèi)容轉(zhuǎn)化成Uint8Array
ints = ints.slice(0, blob.size);
let workBook = xlsx.read(ints, { type: "array" });
let sheetNames = workBook.SheetNames;
let sheetName = sheetNames[0];
let workSheet = workBook.Sheets[sheetName];
//獲取Excle內(nèi)容,并將空內(nèi)容用空值保存
let excelTable = xlsx.utils.sheet_to_json(workSheet, { defval: '' });
// 獲取Excel頭部
let tableThead = Array.from(Object.keys(excelTable[0])).map(
(item) => {
return item
}
);
this.previewData.content = {};
this.previewData.content.tableContent = excelTable;
this.previewData.content.tableThead = tableThead;
this.previewDialogOpen = true;
}
}
注意:
1.vue需要安裝插件xlsx。安裝方式:npm install xlsx
2.引入方式:import * as xlsx from "xlsx"
3.當(dāng)前只考慮excel只有一個(gè)sheet的情況,如果excel有多個(gè),可以遞歸sheetNames,然后讀出所有數(shù)據(jù),再進(jìn)行顯示。sheetNames[0]代表第一個(gè)sheet,以此類推。
結(jié)果:
9.blob流方式的.docx文件
handleWrodFilePreview(blob) {
this.previewDialogOpen = true;
let docx = require("docx-preview");
this.$nextTick(() => {
docx.renderAsync(blob, this.$refs.word);
})
}
<div ref="word">
</div>
注意:
1.vue需要安裝插件docx-preview。安裝方式:npm install docx-preview
2.只能預(yù)覽.docx文件,.doc文件無(wú)法預(yù)覽。
結(jié)果:
10.blob流方式的.pdf文件
handlePdfFilePreview(blob) {
this.previewData.src = URL.createObjectURL(blob);
let loadingTask = pdf.createLoadingTask(this.previewData.src);
loadingTask.promise.then((pdf) => {
this.previewData.pdfPages = pdf.numPages;
})
}
<pdf v-for="pdfPage in previewData.pdfPages" :key="pdfPage" :page="pdfPage" :src="previewData.src"
width="100%">
</pdf>
注意:
1.vue需要安裝插件vue-pdf。安裝方式:npm install vue-pdf
2.引入方式:import pdf from "vue-pdf"
3.components注入方式:
4.如果pdf文件過(guò)大,會(huì)導(dǎo)致瀏覽器崩潰。
components: {
pdf
}
結(jié)果:
11.進(jìn)行下面文件預(yù)覽之前,先將文件地址映射出來(lái)。在ruoyi-admin/src/main/com.ruoyi包下,創(chuàng)建包c(diǎn)onfig,然后在config包下創(chuàng)建MyWebMvcConfig配置類,將文件地址映射出來(lái)。由于使用若依系統(tǒng),為了測(cè)試方便,將映射地址權(quán)限設(shè)置為任何情況下都可以訪問(wèn)。具體方法,打開(kāi)ruoyi-framework/src/main/java/com.ruoyi.framework/config/SecurityConfig.class,在靜態(tài)資源下面添加文件映射地址的訪問(wèn)權(quán)限為任何人可以訪問(wèn)。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Value("${prop.filePath}")
private String filePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 匹配到resourceHandler,將URL映射至location,也就是本地文件夾
registry.addResourceHandler("/data/webFiles/**").addResourceLocations("file:" + filePath);
}
}
.antMatchers("/data/webFiles/**").permitAll()
注意:
1.文件預(yù)覽方式是后端ip(localhost) + : + 后端端口號(hào)(8111) + 文件映射地址(/data/webFile/) + 文件名(48576e3f96d5433bbd35f7cf16b952a6.pdf)。使用默認(rèn)方式的地址為http://localhost:8111/data/webFiles/48576e3f96d5433bbd35f7cf16b952a6.pdf
2.以上面文件映射地址為例,/data/webFile/的作用相當(dāng)于文件路徑d:/csdn/onlineFile/。如果在d:/csdn/onlineFile的文件夾下,有個(gè)test文件夾對(duì)應(yīng)文件路徑為d:/csdn/onlineFile/test/,那么訪問(wèn)此文件夾下的文件,地址訪問(wèn)路徑就會(huì)變成http://localhost:8111/data/webFiles/test/ + 文件名。
3.此種方式預(yù)覽文件,只能預(yù)覽瀏覽器能夠支持的文件格式。
結(jié)果:
文章開(kāi)始提到的另外一種方式就是通過(guò)kkfileview實(shí)現(xiàn)文件預(yù)覽,這種方式能夠快速搭建文件系統(tǒng),支持多種格式的預(yù)覽功能,預(yù)覽速度快,可以作為一個(gè)獨(dú)立的系統(tǒng)使用,不影響主系統(tǒng)架構(gòu),不受瀏覽器、電腦端或手機(jī)端的影響。
后面文章會(huì)有專門(mén)講解kkfileview如何配置和打包使用。
文章鏈接:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-643138.html
支持外網(wǎng)訪問(wèn)的kkfileview文件預(yù)覽系統(tǒng)的詳細(xì)使用過(guò)程文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-643138.html
我也是個(gè)新手,上面很多內(nèi)容不夠完善,甚至有些是錯(cuò)誤的,請(qǐng)大家見(jiàn)諒。這是我在學(xué)習(xí)過(guò)程中做的筆記,感覺(jué)對(duì)大家可能有所幫助才發(fā)出來(lái)的,大家可以選擇性查看。我也是在不斷學(xué)習(xí),不斷完善自己。如果我在學(xué)習(xí)過(guò)程中,感覺(jué)對(duì)大家有用的部分,也會(huì)再次分享給大家的。謝謝!
到了這里,關(guān)于基于若依前后端分離版(Springboot+Vue)的文件預(yù)覽的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!