在 Angular 中提供文件下载
无知的幸福是当你想要下载一个文件时,你登录到一个网站,搜索文件,找到它,点击下载,然后你就完成了,而不知道在那个网站上提供这些文件以供下载的背后的任务和努力 地点。 对于 Web 开发人员来说,提供文件下载可能是一项让您羡慕这些无辜用户的任务。
但是我们如何使用 Angular 框架提供文件供下载呢? 让我们考虑一些方法。
使用 Angular 提供 .txt 文件以供下载
这里的第一种方法是将文本转换为 .txt 格式并提供下载。 要提供文件下载,我们需要使用 blob,这是一种用于直接向浏览器提供文档的虚拟存储。
首先要做的是启动一个新的 Angular 项目。 然后在 app.component.html 文件中,我们将输入以下代码:
代码片段- app.component.html :
<a [href]="fileUrl" download="file.txt">DownloadFile</a>
这将创建网页结构和将被单击以进行下载的链接。
然后我们需要为应用程序创建功能和行为。 我们将在 app.component.ts 文件中执行此操作,如下所示:
代码片段- app.component.ts:
import { Component } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'done';
fileUrl;
constructor(private sanitizer: DomSanitizer) { }
ngOnInit() {
const data = 'some text';
const blob = new Blob([data], { type: 'application/octet-stream' });
this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(blob));
}
}
我们首先定义我们希望保存的数据; 它是一个文本,一些文本。 然后我们定义 Blob 函数并在函数内部声明我们要保存的数据。
我们将使用 DomSanitizer 模块来使我们提供下载的文件能够通过 Angular 的安全测试。 然后我们转到 app.module.ts 文件以导入我们用于创建应用程序的模块。
代码片段- app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
输出:
使用 ngx-filesaver 提供下载文件
现在让我们看看如何使用 Angular 中的 ngx 依赖项来提供文件以供下载。 ngx-filesaver 是一个安全且流行的包,它提供了一种简单的方法来提供文件以供下载。
可以通过在新创建的项目文件夹的目录中键入 npm i ngx-filesaver
来安装 ngx-filesaver。
接下来,我们将导航到 app.component.html 文件并编写这些代码来创建 Web 应用程序的结构。
代码片段- app.component.html:
<h1></h1>
<textarea [(ngModel)]="text"></textarea>
<button type="button" (click)="onDown()">Save Text</button>
在这里,我们创建了一个带有 onDown 事件侦听器的按钮,以便在单击该按钮时下载我们提供的文件。
现在我们必须在 app.component.ts 文件中做真正的工作,如下所示:
代码片段- app.component.ts:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FileSaverService } from 'ngx-filesaver';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'loginfive';
public text = 'hello';
constructor(
private _httpClient: HttpClient,
private _FileSaverService: FileSaverService
) {}
ngOnInit() {}
onDown() {
const fileName = `save.txt`;
const fileType = this._FileSaverService.genType(fileName);
const txtBlob = new Blob([this.text], { type: fileType });
this._FileSaverService.save(txtBlob, fileName);
}
}
您会注意到在 app.component.ts 文件中,我们在按钮标签内声明了 onDown 事件侦听器。 在这里,我们为它定义了函数。
首先,我们声明了将提供下载的数据; 这是一个文本文件。 然后我们利用 blob 提供文件以在浏览器上下载。
这种方法的最后一部分是导入我们用于开发网络应用程序的模块。
代码片段- app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { FileSaverModule } from 'ngx-filesaver';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule,
FormsModule,
HttpClientModule,
FileSaverModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
输出:
使用 Angular 提供 .jpg 文件以供下载
到目前为止,我们一直在研究如何提供 .txt 文件以供下载。 现在让我们看看如何提供图片以供下载。
我们将从一个 URL 中获取图片,下载将显示一个由 Angular Material 提供的进度条。
我们应该首先创建一个新的 Angular 项目并安装 Angular Material 包,导航到项目文件夹并键入:ng add @*angular/material
。
安装成功后,我们将转到 app.component.html 文件来创建页面结构以包含下载进度幻灯片。
代码片段- app.component.html:
<mat-card>
<div class="file">
<p>{{ slides.name }}</p>
<button (click)="download(slides)" mat-raised-button color="primary">Download</button>
</div>
<mat-progress-bar *ngIf="download$ | async as download"
[mode]="download.state == 'PENDING' ? 'buffer' : 'determinate'"
[value]="download.progress">
</mat-progress-bar>
</mat-card>
我们需要创建一个组件,我们将在其中处理代码以观察下载进度,激活材料幻灯片。 我们将创建一个文件,将其命名为 download.ts,并在其中运行这些代码。
代码片段 - download.ts:
import {
HttpEvent,
HttpEventType,
HttpProgressEvent,
HttpResponse
} from "@angular/common/http";
import { Observable } from "rxjs";
import { distinctUntilChanged, scan, map, tap } from "rxjs/operators";
function isHttpResponse<T>(event: HttpEvent<T>): event is HttpResponse<T> {
return event.type === HttpEventType.Response;
}
function isHttpProgressEvent(
event: HttpEvent<unknown>
): event is HttpProgressEvent {
return (
event.type === HttpEventType.DownloadProgress ||
event.type === HttpEventType.UploadProgress
);
}
export interface Download {
content: Blob | any;
progress: number;
state: "PENDING" | "IN_PROGRESS" | "DONE";
}
export function download(
saver?: (b: Blob) => void
): (source: Observable<HttpEvent<Blob>>) => Observable<Download> {
return (source: Observable<HttpEvent<Blob>>) =>
source.pipe(
scan(
(download: Download, event): Download => {
if (isHttpProgressEvent(event)) {
return {
progress: event.total
? Math.round((100 * event.loaded) / event.total)
: download.progress,
state: "IN_PROGRESS",
content: null
};
}
if (isHttpResponse(event)) {
if (saver) {
saver(event.body);
}
return {
progress: 100,
state: "DONE",
content: event.body
};
}
return download;
},
{ state: "PENDING", progress: 0, content: null }
),
distinctUntilChanged((a, b) => a.state === b.state
&& a.progress === b.progress
&& a.content === b.content
)
);
}
由于我们需要观察我们为下载服务的文件的下载进度,所以我们使用 Observable 函数来监测下载进度,然后将其转化为素材滑块。 接下来是创建一个服务文件,该文件将处理从 URL 中获取的文件,然后将其与进度幻灯片一起显示。
让我们创建一个服务文件,将其命名为 download.service.ts,并键入以下代码:
代码片段 - download.service.ts:
import { Injectable, Inject } from '@angular/core'
import { HttpClient, HttpRequest } from '@angular/common/http'
import { download, Download } from './download'
import { map } from 'rxjs/operators'
import { Observable } from 'rxjs'
import { SAVER, Saver } from './saver.provider'
@Injectable({providedIn: 'root'})
export class DownloadService {
constructor(
private http: HttpClient,
@Inject(SAVER) private save: Saver
) {
}
download(url: string, filename?: string): Observable<Download> {
return this.http.get(url, {
reportProgress: true,
observe: 'events',
responseType: 'blob'
}).pipe(download(blob => this.save(blob, filename)))
}
blob(url: string, filename?: string): Observable<Blob> {
return this.http.get(url, {
responseType: 'blob'
})
}
}
为了向我们的应用程序提供这些服务,我们需要一个提供者,创建一个新文件,将其命名为 saver.provider.ts,并将代码放入其中。
代码片段- saver.provider.ts:
import {InjectionToken} from '@angular/core'
import { saveAs } from 'file-saver';
export type Saver = (blob: Blob, filename?: string) => void
export const SAVER = new InjectionToken<Saver>('saver')
export function getSaver(): Saver {
return saveAs;
}
接下来是获取我们要提供下载的图片的 URL。 我们将在 app.component.ts 文件中执行此操作并键入这些代码。
代码片段- app.component.ts:
import { Component, Inject } from '@angular/core';
import { DownloadService } from './download.service'
import { Download } from './download'
import { Observable } from 'rxjs'
import { tap } from 'rxjs/operators'
import { DOCUMENT } from '@angular/common'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'done';
slides =
{name: 'Click here:', url: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_960_720.jpg'}
download$: Observable<Download>
constructor(private downloads: DownloadService,
@Inject(DOCUMENT) private document: Document) {}
download({name, url}: {name: string, url: string}) {
this.download$ = this.downloads.download(url, name)
}
}
我们需要大量的模块来运行应用程序。 我们需要将这些模块导入到 app.module.ts 文件中。
代码片段- app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http'
import {MatButtonModule} from '@angular/material/button';
import {MatProgressBarModule} from '@angular/material/progress-bar';
import {MatCardModule} from '@angular/material/card';
import { BrowserAnimationsModule} from '@angular/platform-browser/animations'
import { AppComponent } from './app.component';
import { SAVER, getSaver } from './saver.provider'
@NgModule({
imports: [
BrowserModule,
FormsModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
MatProgressBarModule,
MatCardModule
],
providers: [{provide: SAVER, useFactory: getSaver}],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
然后我们需要用一些样式来美化页面。 我们将在 app.component.css 文件中添加这个小片段。
代码片段 - app.component.css:
mat-card {
display: flex;
flex-direction: column;
}
.file {
display: flex;
justify-content: space-between;
align-items: center;
}
输出:
总结
根据我们想要提供下载的文件,我们可以采用多种方法在我们的 Angular 应用程序中实现这一点,使用 Angular blob 来保存文件。
相关文章
在 Angular 中上传文件
发布时间:2023/04/14 浏览次数:71 分类:Angular
-
本教程演示了如何在 Angular 中上传任何文件。我们还将介绍如何在文件上传时显示进度条,并在上传完成时显示文件上传完成消息。
Angular 中所有 Mat 图标的列表
发布时间:2023/04/14 浏览次数:91 分类:Angular
-
本教程演示了在哪里可以找到 Angular 中所有 Mat 图标的列表以及如何使用它们。
Angular 2 中的复选框双向数据绑定
发布时间:2023/04/14 浏览次数:139 分类:Angular
-
本教程演示了如何一键标记两个复选框。这篇有 Angular 的文章将着眼于执行复选框双向数据绑定的不同方法。
在 AngularJS 中重新加载页面
发布时间:2023/04/14 浏览次数:142 分类:Angular
-
我们可以借助 windows.location.reload 和 reload 方法在 AngularJS 中重新加载页面。
在 AngularJs 中设置 Select From Typescript 的默认选项值
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程提供了在 AngularJs 中从 TypeScript 中设置 HTML 标记选择的默认选项的解释性解决方案。
在 AngularJS 中启用 HTML5 模式
发布时间:2023/04/14 浏览次数:150 分类:Angular
-
本文讨论如何在 AngularJS 应用程序上启用带有深度链接的 HTML5 模式。
在 AngularJs 中加载 spinner
发布时间:2023/04/14 浏览次数:107 分类:Angular
-
我们将介绍如何在请求加载时添加加载 spinner,并在 AngularJs 中加载数据时停止加载器。
在 Angular 中显示和隐藏
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程演示了 Angular 中的显示和隐藏。在开发商业应用程序时,我们需要根据用户角色或条件隐藏一些数据。我们必须根据该应用程序中的条件显示相同的数据。
在 Angular 中下载文件
发布时间:2023/04/14 浏览次数:104 分类:Angular
-
本教程演示了如何在 angular 中下载文件。我们将介绍如何通过单击按钮在 Angular 中下载文件并显示一个示例。