我目前正在尝试以Excel或CSV格式从我的应用程序中导出一些数据。完成此任务的最佳方法是什么?我应该从后端导出,还是在数据客户端使用Angular 2中的库时导出?我的Web API 2控制器当前生成一个列表,然后将其作为JSON发送到前端。
一切正常,我只是在努力导出列表。
以下是我正在做的事情的样本
[HttpGet]
[Route("/api/preview/{item}")]
public IActionResult Preview(string item)
{
if (item!= null)
{
var preview = _context.dbPreview.FromSql("Exec sampleStoredProcedure {0}, 1", item).ToList();
return Ok(preview);
}
}
这就是我生成发送到Angular 2的数据的方式。
如果有必要,我可以提供任何Angular 2代码但它只是一个普通的服务。不确定是否有一些库可以与Angular 2一起很好地进行导出。我已经看过javascript的一些东西,但alaSQL,但它似乎不适用于Angular 2。
有什么想法吗?
答案 0 :(得分:1)
我已查看Element.getBoundingClientRect()的源代码,我认为您可以使用exportCSV
代码导出数据的csv。
"技巧"是生成以data:text/csv;charset=utf-8
开头的字符串,并由用户下载。
以下代码之类的东西应该对您有用(可能需要稍微修改它以使其适合您的数据)。
除下载方法外,大多数代码都是从PrimeNG复制的。该方法是从PrimeNG DataTable复制的。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
csvSeparator = ';';
value = [
{ name: 'A3', year: 2013, brand: 'Audi' },
{ name: 'Z3', year: 2015, brand: 'BMW' }
];
columns = [
{ field: 'name', header: 'Name' },
{ field: 'year', header: 'Production data' },
{ field: 'brand', header: 'Brand' },
];
constructor() {
console.log(this.value);
this.exportCSV('cars.csv'); // just for show casing --> later triggered by a click on a button
}
download(text, filename) {
let element = document.createElement('a');
element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
exportCSV(filename) {
let data = this.value, csv = '';
// csv = "data:text/csv;charset=utf-8,";
//headers
for (let i = 0; i < this.columns.length; i++) {
if (this.columns[i].field) {
csv += this.columns[i].field;
if (i < (this.columns.length - 1)) {
csv += this.csvSeparator;
}
}
}
//body
this.value.forEach((record, j) => {
csv += '\n';
for (let i = 0; i < this.columns.length; i++) {
if (this.columns[i].field) {
console.log(record[this.columns[i].field]);
// resolveFieldData seems to check if field is nested e.g. data.something --> probably not needed
csv += record[this.columns[i].field]; //this.resolveFieldData(record, this.columns[i].field);
if (i < (this.columns.length - 1)) {
csv += this.csvSeparator;
}
}
}
});
// console.log(csv);
// window.open(encodeURI(csv)); // doesn't display a filename!
this.download(csv, filename);
}
// resolveFieldData(data: any, field: string): any {
// if(data && field) {
// if(field.indexOf('.') == -1) {
// return data[field];
// }
// else {
// let fields: string[] = field.split('.');
// let value = data;
// for(var i = 0, len = fields.length; i < len; ++i) {
// value = value[fields[i]];
// }
// return value;
// }
// }
// else {
// return null;
// }
// }
}
答案 1 :(得分:0)
AWolfs的回答让我走上正轨,但我做了一些调整以使其与Internet Explorer合作。
此函数将我的数组转换为我的csv文件的字符串。 (我必须创建一个新的对象,我的列标题)。然后我只是将我的服务生成的数据传递给函数,然后为我进行解析。对于更复杂的数据,我相信你需要做一些额外的逻辑,但我有基本的文字,所以这一切都适合我。
exportCSV(filename, CsvData) {
let data = CsvData, csv = '';
console.log(data);
//headers
for (let i = 0; i < this.columns.length; i++) {
if (this.columns[i].field) {
csv += this.columns[i].field;
if (i < (this.columns.length - 1)) {
csv += this.csvSeparator;
}
}
}
//body
CsvData.forEach((record, j) => {
csv += '\n';
for (let i = 0; i < this.columns.length; i++) {
if (this.columns[i].field) {
console.log(record[this.columns[i].field]);
csv += record[this.columns[i].field];
if (i < (this.columns.length - 1)) {
csv += this.csvSeparator;
}
}
}
});
this.DownloadFile(csv, filename);
}
这与AWolfs的回答几乎相同,但我不得不对DownloadFile函数进行一些修改,以使其与其他浏览器一起使用。此函数只接受构成.CSV文件和文件名的巨大字符串。
DownloadFile(text, filename) {
console.log(text);
var blob = new Blob([text], { type: 'text/csv;charset=utf-8;' });
if (navigator.msSaveBlob) { // IE 10+
navigator.msSaveBlob(blob, filename);
}
else //create a link and click it
{
var link = document.createElement("a");
if (link.download !== undefined) // feature detection
{
// Browsers that support HTML5 download attribute
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
此代码需要清理,但我想更新我的问题,并为那些在同一件事上苦苦挣扎的人提供答案。这至少应该让你开始。这适用于Chrome和IE。
感谢。