NetSuite Suitelet实现子列表数据CSV导出功能的方法
NetSuite Suitelet实现子列表CSV下载功能
需求背景
已实现通过文本域输入值提交后填充子列表的Suitelet,现需添加「Download CSV」按钮,点击后将子列表数据以CSV格式下载。
实现步骤
1. 添加自定义下载按钮
在表单中新增「下载CSV」按钮,关联客户端脚本函数触发下载请求。
2. 处理CSV生成与下载逻辑
- 客户端:点击按钮时跳转至带下载标识的Suitelet请求地址
- 服务器端:识别下载请求,从会话中读取已存储的子列表数据,生成标准CSV格式内容并设置响应头触发浏览器下载
完整代码示例
服务器端Suitelet脚本
function onRequest(context) { const serverWidget = require('N/ui/serverWidget'); const session = require('N/session'); let form = serverWidget.createForm({ title: 'ABC编号处理器' }); // 添加文本域ABC编号字段 let ABCField = form.addField({ id: 'custpage_input_cidn', type: serverWidget.FieldType.TEXTAREA, label: '输入ABC编号' }); // 添加提交按钮 form.addSubmitButton({ label: '提交' }); // 添加下载CSV按钮,关联客户端触发函数 form.addButton({ id: 'custpage_download_csv', label: '下载CSV', functionName: 'triggerCSVdownload' }); // 绑定客户端脚本(可替换为你的脚本文件ID或路径) form.clientScriptModulePath = './csv_download_client.js'; // 添加子列表及字段 let sublist = form.addSublist({ id: 'custpage_results_sublist', type: serverWidget.SublistType.LIST, label: '销售订单项目' }); sublist.addField({ id: 'custpage_so_number', type: serverWidget.FieldType.TEXT, label: '销售订单号' }); sublist.addField({ id: 'custpage_item_name', type: serverWidget.FieldType.TEXT, label: '项目名称' }); sublist.addField({ id: 'custpage_quantity', type: serverWidget.FieldType.INTEGER, label: '数量' }); // POST请求:填充子列表并存储数据到会话 if (context.request.method === 'POST') { let abcNumbers = context.request.parameters.custpage_input_cidn; // 替换为你的实际子列表填充逻辑 let sublistData = [ { so: 'SO123', item: 'Item A', qty: 5 }, { so: 'SO456', item: 'Item B', qty: 10 } ]; // 填充子列表 sublistData.forEach((row, index) => { sublist.setSublistValue({ id: 'custpage_so_number', line: index, value: row.so }); sublist.setSublistValue({ id: 'custpage_item_name', line: index, value: row.item }); sublist.setSublistValue({ id: 'custpage_quantity', line: index, value: row.qty }); }); // 将数据存入会话,供下载时读取 session.set({ name: 'sublist_data', value: JSON.stringify(sublistData) }); } // 处理CSV下载请求 if (context.request.parameters.action === 'download_csv') { let sublistData = JSON.parse(session.get({ name: 'sublist_data' }) || '[]'); if (sublistData.length === 0) { context.response.write('无数据可下载,请先提交生成子列表'); return; } // 生成CSV内容(处理特殊字符避免格式错误) let csvHeader = '销售订单号,项目名称,数量\n'; let csvRows = sublistData.map(row => { // 含逗号/引号的字段用双引号包裹,内部引号转义为双引号 const escapeField = val => `"${(val || '').replace(/"/g, '""')}"`; return `${escapeField(row.so)},${escapeField(row.item)},${row.qty}`; }).join('\n'); let csvContent = csvHeader + csvRows; // 设置响应头触发下载 context.response.setHeader({ name: 'Content-Type', value: 'text/csv' }); context.response.setHeader({ name: 'Content-Disposition', value: 'attachment; filename="销售订单项目.csv"' }); context.response.write(csvContent); return; // 终止后续表单渲染,直接输出CSV } context.response.writePage(form); }
客户端脚本(csv_download_client.js)
function triggerCSVdownload() { // 构造下载请求URL,添加action参数标识下载操作 let baseUrl = window.location.href.split('?')[0]; window.location.href = `${baseUrl}?action=download_csv`; }
关键注意事项
- 数据存储:因GET请求无法直接读取前端子列表动态数据,需在POST填充时将数据存入
session供下载时读取 - CSV格式兼容:必须处理字段中的逗号、双引号等特殊字符,避免CSV解析错误
- 响应头配置:通过
Content-Disposition头指定下载文件名,确保浏览器触发下载而非直接显示内容
内容的提问来源于stack exchange,提问作者Maira S
相关产品推荐
相关产品推荐

