以表格.csv格式在HTML中显示逗号分隔的字符串



我在Typescript文件中构建了一个逗号分隔的字符串。这可以导出为"file.csv",下载后所有内容都会正确显示。

我想要实现的是在下载这个字符串之前创建一个"预览"。我希望预览类似于HTML表,或者它在CSV中的显示方式。

示例字符串

1,Header1, Header2, Header3, Header4,
2,0,1,"Content","More Content","

当然,在CSV中,这看起来与上面的内容相同,但在边界/单元格中是分开的。

有可能在HTML中实现这一点吗?

下面是我在stackblitz上创建的一个示例:https://stackblitz.com/edit/angular-k162aa

下面用内联注释描述了主要的CSV解析功能:

// CSV is assumed to have headers as well
csvToJSON(csv: string) {
const lines: string[] = csv
// escape everything inside quotes to NOT remove the comma there
.replace(/"(.*?)"/gm, (item) => encodeURIComponent(item))
// split by lines
.split('n');
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: any[] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
// remove trailing spaces and quotes
lineObj[valueName] = lineValues[index]
// handle quotes
.replace(/%22(.*?)%22/gm, (item) => decodeURIComponent(item))
// trim trailing spaces
.trim();
})
return lineObj; // return lineValues for array representation.
}); 
return { data, headers };
}
csvToJSON(csv: string) {
const lines: string[] = csv.split('n');
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: string[][] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
lineObj[valueName] = lineValues[index];
});
return lineObj; // return lineValues for an array.
}); 
return { data, headers };
}

请注意,注释后的代码可以为您提供一个数组数组,而代码按原样返回一个对象数组。

在HTML中,这种格式更容易呈现,因为标题的索引与每个项目数组的索引相同:

<table class="table">
<thead>
<tr>
<th *ngFor="let header of headers">{{ header }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data">
<td *ngFor="let header of headers">
{{ row[header] }}
</td>
</tr>
</tbody>
</table>

为了支持行标题,可以使用以下html片段作为表体部分:

<tr *ngFor="let row of data">
<ng-container *ngFor="let attribute of row; let i = index">
<td *ngIf="i">{{ attribute }}</td>
<th *ngIf="!i">{{ attribute }}</th>
</ng-container>
</tr>

您的问题实际上混合了两个问题,

  1. 解析csv和
  2. 呈现其数据

上述每个任务都有自己的陷阱,虽然创建一个简单的解析器和呈现代码很容易,但通过使用专门用于这些任务的第三方代码,避免未来的痛苦要容易得多。如果你选择得好(是的,有很多选择(,你就不必担心覆盖边界条件、大小限制、性能瓶颈、错误处理、XSS漏洞(从数据中注入,但你应该评估库漏洞(。

如果这是我的项目,我会选择像Papa Parse和DataTables这样的东西来进行解析和表示。检查DataTables csv导入示例页面:https://editor.datatables.net/examples/extensions/import

另一方面,如果你想挑战所有这些,并且你确信数据总是会正常工作,那么一定要编写自己的代码!

最新更新