![](/img/trans.png)
[英]How can I create an html table, with unknown number of columns per row, get the columns to be aligned, and have an id for each cell/row?
[英]How to generating table that will have 3 columns per row
我使用 Vue 2。
我從集合中生成表:
<table class="table table-striped table-bordered">
<tbody>
<tr v-for="(type, typeIndex) in getAllUpgradeTypes" :key="typeIndex">
<td>
<imageDesc
style="margin-left: 10px"
:title="type"
:text="'Select an Option'"
:zoneId="selectedZone.id"
/>
</td>
</tr>
</tbody>
</table>
目前,創建的表是多行的,每行只有一列,並且在列內顯示一項。
我的問題是如何生成每行包含 3 列的表?
您至少可以使用幾種不同的模式。 一種涉及在模板中迭代數據之前重新排列數據,另一種則不需要。 我會告訴你兩個。
在這兩種情況下,都使用數據屬性來保存列數:
data: () => ({
numCols: 3
})
而不是一個包含所有項目的數組,而是使用計算將數據重新組織成一個多維的行和列數組:
computed: {
arrangedData() {
const arrangedData = [];
this.getAllUpgradeTypes.forEach((item, index) => {
if (index % this.numCols === 0) {
arrangedData.push([])
}
arrangedData[arrangedData.length - 1].push(item);
});
return arrangedData;
}
}
像這樣迭代數據:
<table class="table table-striped table-bordered">
<tr v-for="(row, rowIndex) in arrangedData" :key="rowIndex">
<td v-for="(type, typeIndex) in row" :key="`${rowIndex}:${typeIndex}`">
{{ type }}
</td>
</tr>
</table>
這是一個演示:
new Vue({ el: "#app", data: () => ({ getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], numCols: 3 }), computed: { arrangedData() { const arrangedData = []; this.getAllUpgradeTypes.forEach((item, index) => { if (index % this.numCols === 0) { arrangedData.push([]) } arrangedData[arrangedData.length - 1].push(item); }); return arrangedData; } } });
td { width: 40px }
<div id="app"> <table class="table table-striped table-bordered"> <tr v-for="(row, rowIndex) in arrangedData":key="rowIndex"> <td v-for="(type, typeIndex) in row":key="`${rowIndex}:${typeIndex}`"> {{ type }} </td> </tr> </table> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
另一種方法涉及使用計算來計算行數。 它的代碼更少,但是type
在模板中得到了一個丑陋的語法:
computed: {
numRows() {
return Math.ceil(this.getAllUpgradeTypes.length / this.numCols);
}
}
像這樣迭代數據:
<table class="table table-striped table-bordered">
<tr v-for="(row, indexRow) in numRows">
<td v-for="(col, indexCol) in numCols">
{{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }}
</td>
</tr>
</table>
這是一個演示:
new Vue({ el: "#app", data: () => ({ getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'], numCols: 3 }), computed: { numRows() { return Math.ceil(this.getAllUpgradeTypes.length / this.numCols); } } });
td { width: 40px; }
<div id="app"> <table> <tr v-for="(row, indexRow) in numRows":key="indexRow"> <td v-for="(type, indexCol) in numCols":key="`${rowIndex}:${typeIndex}`"> {{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }} </td> </tr> </table> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
這些選項可能有一些變化,但我認為第一個可能是模板清晰度的最佳選擇。
這是我對類似問題的解決方案。 我需要生成一個可打印的頁面並從我們數據庫中的表中顯示信息。 頁面的外觀要求我每行有 3 個固定大小的行和 3 個固定大小的列。
我添加了樣式以使其具有類似網格的外觀,但這是我在 3 行后生成帶有分頁符的表格的方式:
這是我在 HTML (cshtml) 文件中設置表的地方:
<table id="employee-table" class="m-auto">
</table>
這是我的 JavaScript function,它位於外部 JS 文件中(如果您是這樣設置的,請不要忘記在 HTML 中引用該文件)
function GeneratePrintablePDF(employeeData) {
document.getElementById('loader').classList.add('hidden'); //this is just the "loading" spinner for when the page is loading
dataContainer = document.getElementById('employee-table');
numberOfRows = employeeData.length / 3;
if (employeeData % 3 != 0) {
numberOfRows = Math.trunc(numberOfRows);
numberOfRows += 1;
}
var emp = 0;
do
{
for (var row = 1; row <= numberOfRows; row++) {
var tableRowDiv = document.createElement('div');
dataContainer.appendChild(tableRowDiv);
var tableRow = document.createElement('tr');
tableRowDiv.appendChild(tableRow);
for (var col = 1; col < 4; col++)
{
if (emp < employeeData.length) {
var tableCol = document.createElement('td');
tableCol.className = 'pdf-employee-box';
tableRow.appendChild(tableCol);
var empName = document.createElement('div');
empName.className = 'fw-bold';
empName.innerHTML = `${employeeData[emp].firstName} ${employeeData[emp].lastName}`;
tableCol.appendChild(empName);
var empPhoto = document.createElement('img');
var employeePhotoUrl = employeeData[emp].azurePhotoURL;
if (employeePhotoUrl == null) {
empPhoto.src = '/Images/lg_unavailable.jpg';
} else {
empPhoto.src = employeePhotoUrl;
}
var empPhotoOnError = document.createAttribute('onerror');
empPhotoOnError.value = "this.onerror=null;this.src='/Images/lg_unavailable.jpg';";
empPhoto.setAttributeNode(empPhotoOnError);
empPhoto.alt = 'Employee Photo';
empPhoto.className = 'employee-photo-pdf pdf-image';
tableCol.appendChild(empPhoto);
var empTitle = document.createElement('div');
empTitle.innerHTML = employeeData[emp].title != null ? `Title: ${employeeData[emp].title}` : 'Title: Unknown';
empTitle.className = 'pdf-details';
tableCol.appendChild(empTitle);
var empDept = document.createElement('div');
empDept.innerHTML = employeeData[emp].department != null ? `Department: ${employeeData[emp].department}` : 'Department: Unknown';
empDept.className = 'pdf-details';
tableCol.appendChild(empDept);
var empEmail = document.createElement('div');
empEmail.innerHTML = (employeeData[emp].emailAddress != null && !employeeData[emp].emailAddress.toLowerCase().includes('no ')) ? `Email: ${employeeData[emp].emailAddress}` : 'Email: Unknown/None';
empEmail.className = 'pdf-details';
tableCol.appendChild(empEmail);
var empStartDate = document.createElement('div');
empStartDate.innerHTML = employeeData[emp].startDate != null ? `Start Date: ${employeeData[emp].startDate}` : 'Start Date: Unknown';
empStartDate.className = 'pdf-details';
tableCol.appendChild(empStartDate);
var empLocation = document.createElement('div');
empLocation.innerHTML = employeeData[emp].location != null ? `Location: ${employeeData[emp].location}` : 'Location: Unknown';
empLocation.className = 'pdf-details';
tableCol.appendChild(empLocation);
if (col == 2) tableCol.className = tableCol.className + ' pdf-grid-lines';
emp++;
}
}
if (emp % 9 == 0) {
tableRowDiv.className += 'page-break-after';
}
}
} while (emp < employeeData.length)
}
我決定根據我們有多少員工記錄來計算我需要的行數。 所以,如果我們有 436 名員工,那么我確定我需要 146 行。 所以我正在對其進行編程以生成我需要的精確行數,並且每行只放置 3 個項目(列)。 在這種情況下,第 146 行只有 1 條記錄。
如您所見,我的循環中的代碼僅在到達最后一個員工之前運行,因此它不會引發索引超出范圍異常。
這個特定的代碼是我告訴表格跳到下一頁的地方,這樣員工記錄就不會跑到另一個頁面上並拆分信息。
if (emp % 9 == 0) {
tableRowDiv.className += 'page-break-after';
}
這是我在外部 CSS 文件中引用的 CSS:
@media print {
.page-break-after {
break-after: page;
}
}
我知道我絕不是最終的編程大師,所以可能有更好或更簡單的方法來做到這一點。 然而,這就是我如何讓它在我的環境中工作的方式,它在不使用某些框架或庫的情況下完成了我需要它做的事情。
我在研究中發現許多 PDF 生成器框架、庫等現在都需要許可。 因此,如果生成可打印的文檔是您的目標,那么這也適用於您。 無論如何,祝你好運,我希望我幫助了某人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.