使用自定义名称导出文件
Export file with custom name
我想实现这个用于从 Spring BE 导出数据的代码示例。
@GetMapping("export/{ids}")
public void export(HttpServletResponse response, @PathVariable List<Integer> ids) {
List<Transactions> transactions = (List<Transactions>) transactionService.findAll(ids);
List<TransactionExcelEntry> entries = transactions.stream().map(payment_transaction_mapper::toExcel).collect(Collectors.toList());
List<String> headers = Arrays.asList("Id", "Name", "Type", "Created at");
try {
response.addHeader("Content-disposition", "attachment; filename=Transactions.xlsx");
response.setContentType("application/vnd.ms-excel");
new SimpleExporter().gridExport(headers, entries, "id, name", response.getOutputStream());
response.flushBuffer();
} catch (IOException ex) {
LOG.debug("parsing of transactions failed");
}
}
导出按钮:
<button class="dropdown-item" (click)="export()">XLS</button>
导出功能:
export() {
var newPagination = new Pagination();
newPagination.size = this.pagination.size * this.pagination.total
this.transactionService.search(newPagination, this.formGroup.value)
.subscribe(result => {
this.formGroup.enable();
const query = result.content.map(t => t.id).join(',');
this.transactionService.exportRows(query).subscribe(data => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(data);
a.download = 'export.xls';
a.click();
});
}, (error) => {
this.formGroup.enable();
});
}
exportRows(query) {
return this.http.get(`/api/transactions/export`, { responseType: 'blob' });
}
我想生成文件名到Java BE 并从Angular FE 下载。如何实现此功能?
您可以通过访问响应 header 并检索 Content-Disposition
.
来检索 blob 的文件名
为此,请通过提供额外的选项 observe: 'response'
.
稍微更改您的 HttpClient.get
调用
为了清楚起见,我们创建了一个专用的 ExportResponse
来仅向我们的 component/or 其他服务方法公开需要的数据:
export type ExportResponse = {
blob: Blob,
fileName: string
}
exportRows
检索 Response Headers
:
exportRows(query): ExportResponse {
return this.http.get(`/api/transactions/export`, {
observe: 'response',
responseType: 'blob'
}.pipe(
map(response => {
const contentDisposition = response.headers.get('content-disposition');
return {
blob: response.body,
fileName: getContentDispositionFileName(contentDisposition)
}
})
);
}
getContentDispositionFileName
方法负责从收到的header中提取文件名:
getContentDispositionFileName(contentDisposition: string) {
let filename = 'default-file-name';
var filenameRegex = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/;
var matches = filenameRegex.exec(contentDisposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
return filename;
}
此 RegExp 模式来自 Winter Soldier's answer,并提取了文件名的部分。
然后你可以在初始方法中使用ExportResponse
:
this.transactionService.exportRows(query).subscribe(response => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(response.blob);
a.download = response.fileName;
a.click();
});
重要提示
如果您启用了 CORS
,请小心允许您的后端发送并授权您的 frond-end 访问 Content-Disposition
header.
为此,请在您的回复中添加 Access-Control-Expose-Headers: Content-Disposition
。
response.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
如果你想自动生成文件名可以试试下面的方法
export(filename) {
this.transactionService.search(newPagination, this.formGroup.value)
.subscribe(result => {
this.formGroup.enable();
const timeStamp: number = new Date().getTime();
const query = result.content.map(t => t.id).join(',');
this.transactionService.exportRows(query).subscribe(data => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(data);
a.download = `${fileName}-${timeStamp}.xls`;
a.click();
});
}, (error) => {
this.formGroup.enable();
});
}
单击按钮可以发送文件名,或者通过服务调用可以从服务器获取文件名
<button class="dropdown-item" (click)="export('Transaction')">XLS</button>
我想实现这个用于从 Spring BE 导出数据的代码示例。
@GetMapping("export/{ids}")
public void export(HttpServletResponse response, @PathVariable List<Integer> ids) {
List<Transactions> transactions = (List<Transactions>) transactionService.findAll(ids);
List<TransactionExcelEntry> entries = transactions.stream().map(payment_transaction_mapper::toExcel).collect(Collectors.toList());
List<String> headers = Arrays.asList("Id", "Name", "Type", "Created at");
try {
response.addHeader("Content-disposition", "attachment; filename=Transactions.xlsx");
response.setContentType("application/vnd.ms-excel");
new SimpleExporter().gridExport(headers, entries, "id, name", response.getOutputStream());
response.flushBuffer();
} catch (IOException ex) {
LOG.debug("parsing of transactions failed");
}
}
导出按钮:
<button class="dropdown-item" (click)="export()">XLS</button>
导出功能:
export() {
var newPagination = new Pagination();
newPagination.size = this.pagination.size * this.pagination.total
this.transactionService.search(newPagination, this.formGroup.value)
.subscribe(result => {
this.formGroup.enable();
const query = result.content.map(t => t.id).join(',');
this.transactionService.exportRows(query).subscribe(data => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(data);
a.download = 'export.xls';
a.click();
});
}, (error) => {
this.formGroup.enable();
});
}
exportRows(query) {
return this.http.get(`/api/transactions/export`, { responseType: 'blob' });
}
我想生成文件名到Java BE 并从Angular FE 下载。如何实现此功能?
您可以通过访问响应 header 并检索 Content-Disposition
.
为此,请通过提供额外的选项 observe: 'response'
.
HttpClient.get
调用
为了清楚起见,我们创建了一个专用的 ExportResponse
来仅向我们的 component/or 其他服务方法公开需要的数据:
export type ExportResponse = {
blob: Blob,
fileName: string
}
exportRows
检索 Response Headers
:
exportRows(query): ExportResponse {
return this.http.get(`/api/transactions/export`, {
observe: 'response',
responseType: 'blob'
}.pipe(
map(response => {
const contentDisposition = response.headers.get('content-disposition');
return {
blob: response.body,
fileName: getContentDispositionFileName(contentDisposition)
}
})
);
}
getContentDispositionFileName
方法负责从收到的header中提取文件名:
getContentDispositionFileName(contentDisposition: string) {
let filename = 'default-file-name';
var filenameRegex = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/;
var matches = filenameRegex.exec(contentDisposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
return filename;
}
此 RegExp 模式来自 Winter Soldier's answer,并提取了文件名的部分。
然后你可以在初始方法中使用ExportResponse
:
this.transactionService.exportRows(query).subscribe(response => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(response.blob);
a.download = response.fileName;
a.click();
});
重要提示
如果您启用了 CORS
,请小心允许您的后端发送并授权您的 frond-end 访问 Content-Disposition
header.
为此,请在您的回复中添加 Access-Control-Expose-Headers: Content-Disposition
。
response.addHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
如果你想自动生成文件名可以试试下面的方法
export(filename) {
this.transactionService.search(newPagination, this.formGroup.value)
.subscribe(result => {
this.formGroup.enable();
const timeStamp: number = new Date().getTime();
const query = result.content.map(t => t.id).join(',');
this.transactionService.exportRows(query).subscribe(data => {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(data);
a.download = `${fileName}-${timeStamp}.xls`;
a.click();
});
}, (error) => {
this.formGroup.enable();
});
}
单击按钮可以发送文件名,或者通过服务调用可以从服务器获取文件名
<button class="dropdown-item" (click)="export('Transaction')">XLS</button>