将dataview查询的长列表内容如何分栏显示?

用dataview查询客户汇总表,由于客户数量会与日俱增,到时会显示很长一串,影响阅读。查询结果显示的仅有客户名称一栏,所以希望能分栏显示,比如分3-4栏显示,这个栏的高度会随着数量的增加而增长。同时希望,点击客户名称能跳转到相应的客户名称的总览表上。

用deepseek试过dataviewjs,采用html方式分栏等等,要么能分栏,但不能点击跳转,要么就假分栏,还是竖向排列。最后它让我手动输入写死算了。:rofl:


不知各位大佬,有没有什么好办法。

const customers = dv.pages('"10_Projects"')
    .where(p => p.customer != null && p.project != null)
    .groupBy(p => p.customer)
    .key
    .sort();

const total = customers.length;

// ========================================
// 智能计算列数
// ========================================
let columns = 2;
if (total > 10) columns = 3;
if (total > 20) columns = 4;
if (total > 35) columns = 5;

const perColumn = Math.ceil(total / columns);

// ========================================
// 按列分组数据
// ========================================
const columnData = [];
for (let j = 0; j < columns; j++) {
    const col = [];
    for (let i = 0; i < perColumn; i++) {
        const idx = i + j * perColumn;
        if (idx < total) {
            const c = customers[idx];
            col.push('[[' + c + '/' + c + '|' + c + ']]');
        }
    }
    columnData.push(col);
}

// ========================================
// 用 HTML 表格实现分栏
// ========================================
let html = '<div style="margin-top: 8px;">';
html += '<table style="width: 100%; border-collapse: collapse;">';
html += '<tr>';

for (let j = 0; j < columns; j++) {
    const col = columnData[j];
    html += '<td style="vertical-align: top; padding: 4px 20px 4px 0; border: none; width: ' + (100/columns) + '%;">';
    html += '<ul style="list-style: none; padding-left: 0; margin: 0;">';
    for (const item of col) {
        html += '<li style="padding: 3px 0;">• ' + item + '</li>';
    }
    html += '</ul>';
    html += '</td>';
}

html += '</tr>';
html += '</table>';
html += '</div>';

dv.paragraph("📊 共 **" + total + "** 个客户,分 **" + columns + "** 栏显示");
dv.span(html);

呵呵,用workburry解决了。

需要分栏,直接复制这个模板,改一下 pages 查询和 links 生成逻辑就行
```dataviewjs
// ═══════════════════════════════════════════════
//  分栏显示 — 通用模板
// ═══════════════════════════════════════════════

// ── ① 查询数据 ──
const pages = dv.pages('"10_Projects"')
    .where(p => p.customer != null && p.project != null)
    .groupBy(p => p.customer)
    .key
    .sort();

const total = pages.length;

// ── ② 分栏参数 ──
const maxCols = 5;
const perCol = 8;
const numCols = Math.max(1, Math.min(Math.ceil(total / perCol), maxCols));
const chunk = Math.ceil(total / numCols);

// ── ③ 生成链接 ──
const links = pages.map(c => '[[' + c + '/' + c + '|' + c + ']]');

// ── ④ 显示统计 ──
dv.paragraph("📊 共 **" + total + "** 个客户,分 **" + numCols + "** 栏显示");

// ── ⑤ 渲染分栏 ──
dv.list(links);

const ul = dv.container.querySelector('ul');
if (ul) {
    const items = Array.from(ul.children);
    ul.remove();

    const row = document.createElement('div');
    row.style.display = 'flex';
    row.style.flexWrap = 'wrap';
    row.style.gap = '24px';
    row.style.alignItems = 'flex-start';

    for (let c = 0; c < numCols; c++) {
        const col = document.createElement('div');
        col.style.flex = '1 1 0';
        col.style.minWidth = '120px';

        const colUl = document.createElement('ul');
        colUl.style.margin = '0';
        colUl.style.paddingLeft = '20px';

        for (let i = c * chunk; i < Math.min((c + 1) * chunk, total); i++) {
            colUl.appendChild(items[i]);
        }
        col.appendChild(colUl);
        row.appendChild(col);
    }

    dv.container.appendChild(row);
}
```