Node.js中使用cli-table无法正常展示数据问题求助
嘿,我看你用cli-table2来展示API返回的数据,API调用环节都没问题,就是输出表格的时候出状况了。从你贴的代码片段来看,我整理了几个最可能踩的坑和对应的解决办法,应该能帮你搞定:
1. 列宽配置必须和表头数量匹配
你代码里写的colWidths: [10, 10, 10...明显没写完,cli-table2要求colWidths数组的长度必须和head数组的长度完全一致。数一下你的表头,一共13个字段,所以colWidths也得是13个数值的数组,少一个都会导致表格直接变形。
比如你可以根据每个字段的实际数据长度来调整:
colWidths: [10, 10, 10, 12, 10, 12, 20, 15, 10, 15, 12, 12, 30]
像summary这种文本较长的字段,记得给个足够的宽度,或者配合下面的自动换行功能。
2. 长文本要开启自动换行
默认情况下,cli-table2不会自动换行长文本,遇到像summary、OfficialSite这类内容较长的字段,直接会撑破表格的布局。你只需要在初始化Table的时候加上wordWrap: true配置,就能让内容自动适配列宽换行:
let table = new Table({ head: ['Name', 'Type', 'Language', 'Genres', 'Status', 'Premiered', 'OfficialSite', 'Schedule', 'Rating', 'Streamed On', 'Externals', 'Images', 'summary'], colWidths: [10, 10, 10, 12, 10, 12, 20, 15, 10, 15, 12, 12, 30], wordWrap: true // 关键配置:开启自动换行 });
3. 特殊格式数据要提前处理
API返回的数据里,很多字段不是纯字符串——比如Genres是数组、Rating是对象、Images是URL,直接塞到表格里会显示[object Object]或者乱码一样的数组字符串,看起来特别糟。你得先把这些数据转换成友好的字符串格式:
// 假设单条API数据是show对象,处理后再添加到表格 const processedRow = [ show.name || 'N/A', show.type, show.language, show.genres?.join(', ') || 'N/A', // 数组转逗号分隔的字符串 show.status, show.premiered, show.officialSite || 'N/A', show.schedule ? `${show.schedule.time} (${show.schedule.days?.join(', ') || 'N/A'})` : 'N/A', // 格式化日程 show.rating?.average || 'N/A', show.network?.name || show.webChannel?.name || 'N/A', `${show.externals?.tvrage || 'N/A'}, ${show.externals?.thetvdb || 'N/A'}`, // 合并外部ID show.image?.medium || 'No Image', // 用缩略图URL或者提示文本 show.summary ? show.summary.replace(/<[^>]+>/g, '') : 'N/A' // 去掉HTML标签 ]; table.push(processedRow);
要是字段内容太长,还可以加个截断处理,比如show.name?.substring(0,9) + (show.name?.length>9?'...':''),避免单个内容撑爆列宽。
4. 注意控制台窗口宽度限制
如果你的表格总宽度超过了当前控制台的窗口宽度,cli-table2也会出现布局错乱的问题。可以先调整列宽的总和,让它适配常见的控制台宽度(比如80-120字符左右),或者提醒用户放大控制台窗口。
最后给你一个完整的示例代码参考,把上面的点都整合进去了:
const url = require('./url'), Table = require('cli-table2'), fs = require('fs'), inquirer = require('inquirer'); // 模拟API获取数据的函数,替换成你实际的调用逻辑 async function fetchShows() { // 这里可以写你的API请求代码,比如axios.get(url)之类的 return [ // 示例数据,和你API返回的结构一致就行 { name: "Stranger Things", type: "Scripted", language: "English", genres: ["Drama", "Fantasy", "Horror"], status: "Running", premiered: "2016-07-15", officialSite: "https://www.netflix.com/title/80057281", schedule: { time: "20:00", days: ["Friday"] }, rating: { average: 8.7 }, network: { name: "Netflix" }, externals: { tvrage: 34683, thetvdb: 296762 }, image: { medium: "https://example.com/image.jpg" }, summary: "<p>When a young boy vanishes, a small town uncovers a mystery involving secret experiments, terrifying supernatural forces, and one strange little girl.</p>" } ]; } async function renderShowTable() { const shows = await fetchShows(); // 初始化表格,配置好表头、列宽和自动换行 const table = new Table({ head: ['Name', 'Type', 'Language', 'Genres', 'Status', 'Premiered', 'OfficialSite', 'Schedule', 'Rating', 'Streamed On', 'Externals', 'Images', 'summary'], colWidths: [10, 10, 10, 12, 10, 12, 20, 15, 10, 15, 12, 12, 30], wordWrap: true, style: { head: ['green'], // 可选:给表头加颜色,更醒目 border: ['cyan'] } }); // 处理每条数据并添加到表格 shows.forEach(show => { table.push([ // 对超长内容进行截断,避免撑爆列宽 show.name?.substring(0,9) + (show.name?.length>9?'...':'') || 'N/A', show.type, show.language, show.genres?.join(', ') || 'N/A', show.status, show.premiered, show.officialSite?.substring(0,19) + (show.officialSite?.length>19?'...':'') || 'N/A', show.schedule ? `${show.schedule.time} (${show.schedule.days?.join(', ') || 'N/A'})` : 'N/A', show.rating?.average || 'N/A', show.network?.name || show.webChannel?.name || 'N/A', `${show.externals?.tvrage || 'N/A'}, ${show.externals?.thetvdb || 'N/A'}`, show.image?.medium?.substring(0,11) + (show.image?.medium?.length>11?'...':'') || 'No Image', show.summary ? show.summary.replace(/<[^>]+>/g, '').substring(0,29) + (show.summary.length>29?'...':'') : 'N/A' ]); }); // 输出最终的表格 console.log(table.toString()); } // 执行渲染 renderShowTable();
你可以根据自己的API返回结构调整数据处理的部分,应该就能正常显示表格了!
内容的提问来源于stack exchange,提问作者JavaDeveloper

