kes*_*hra 1 ionic-framework capacitor
我正在开发带有电容器 5 的 Angular Ionic 7 应用程序。我的应用程序的一页是不同文件的列表(pdf、txt、csv)。用户可以选择一个文件,它应该下载到设备上。我尝试创建一个对象 Url 并使用 window.open(fileURL) 打开它,但没有任何反应,也没有错误。我尝试了带有 downloadFile() Api 的库 @capacitor/filesystem 。结果包含一个 blob,但我无法将其存储在设备上。有人知道怎么做这个吗?
Filesystem.downloadFile({ path: Directory.Data, url: url, directory: Directory.Data }).then((res) => {
console.log('download finished');
});
Run Code Online (Sandbox Code Playgroud)
我们将使用电容器社区的FileOpener 库。与write_blob 库一起使用,它不是必需的,但更快、更可靠。
npm install @capacitor-community/file-opener
npm install capacitor-blob-writer
npx cap sync
Run Code Online (Sandbox Code Playgroud)
npm install @capacitor-community/file-opener
npm install capacitor-blob-writer
npx cap sync
Run Code Online (Sandbox Code Playgroud)
// Not required step, just cleaner ;)
export interface CustomFile {
title: string,
url: string,
path: string,
mineType: string
}
Run Code Online (Sandbox Code Playgroud)
这段代码大量使用了文件系统,这里有一些小帮助可以指导您
// 2. Import it into your file (I'm using a services)
import { FileOpener, FileOpenerOptions } from '@capacitor-community/file-opener'
import write_blob from 'capacitor-blob-writer'
import { Directory, Filesystem } from '@capacitor/filesystem'
@Injectable({
providedIn: 'root',
})
export class OpenLinkService {
progress = 0 // If you wish to show a loader :)
downloadingUrls = [] // Avoid downloading multiple time the same asset
constructor() {}
// 3. We'll be preparing & downloading the file
private async _downloadAndOpenFiles(file: CustomFile) {
if(this.downloadingUrls.includes(file.url)) return
this.downloadingUrls.push(file.url)
this._httpClient
.get(url, {
responseType: 'blob',
reportProgress: true,
observe: 'events',
})
.subscribe({
next: async (event) => {
if (event.type === HttpEventType.DownloadProgress) {
this.progress = Math.round((100 * event.loaded) / event.total)
} else if (event.type === HttpEventType.Response) {
this.progress = 100
const filePath = await this._getFilePath(file.title, event.body)
await this._openFileWithType(filePath, file.mineType)
this.progres = 100
this.downloadingUrls = this.downloadingUrls.filter((dUrl) => dUrl !== file.url)
}
},
error: (error) => {
console.error(error)
},
})
}
// 4 Method to retrieve the fiel we've saved
private async _getFilePath(fileName: string, blob: Blob): Promise<string> {
const name = fileName
try {
// 5. Save the file locally
return await this._saveBlobFile(blob, name)
} catch {
// 6. In case the file did already exists -> we retrieve it
await Filesystem.getUri({
path: name,
directory: Directory.Cache,
})
.then((savedFile) => {
return savedFile.uri
})
.catch((error) => {
console.error(error)
throw new Error('Cannot save/open the file')
})
}
}
// 5. Save the file locally
private _saveBlobFile(blob: Blob, fileName: string) {
return write_blob({
path: fileName,
directory: Directory.Cache,
blob: blob,
})
}
// 7. Open the file
private async _openFileWithType(filePath: string, fileType: string) {
const fileOpenerOptions: FileOpenerOptions = {
filePath: filePath,
contentType: fileType,
}
await FileOpener.open(fileOpenerOptions)
.then(() => {
// 'File is opened'
})
.catch((error) => {
console.error(error)
})
}
// Bonus: Localhost:4200. A little more code, to make it work even while testing on your laptop ;)
public async openFile(file: CustomFile) {
if (!file?.url) return
try {
this._downloadAndOpenFiles(file)
} catch (error) {
console.error(error)
Browser.open({ url: file.path })
}
}
Run Code Online (Sandbox Code Playgroud)
干杯