技术问询:如何使用SuiteScript 2.0上传本地文件至NetSuite文件柜
使用SuiteScript 2.0将本地文件上传至NetSuite文件柜的实现方案
嘿,我来给你拆解两种最实用的实现方案,直接抄代码改改就能落地——毕竟NetSuite客户端脚本没法直接操作文件柜写入,必须靠服务器端脚本(Suitelet/RESTlet)来兜底完成存储,核心逻辑就是「客户端选文件 → 服务器端接收并保存到文件柜」。
方案一:Suitelet + 内置上传表单(适合快速搭建上传页面)
这种方式最省心,直接用Suitelet生成带文件上传控件的表单,用户在浏览器里选文件提交就行,完全不需要额外的前端开发。
1. 编写Suitelet服务器脚本
这个脚本要干两件事:GET请求返回上传表单,POST请求处理文件并保存到文件柜。
/** * @NApiVersion 2.x * @NScriptType Suitelet */ define(['N/ui/serverWidget', 'N/file', 'N/log'], function(serverWidget, file, log) { function onRequest(context) { if (context.request.method === 'GET') { // 生成带文件上传字段的表单 var uploadForm = serverWidget.createForm({ title: '本地文件上传至NetSuite文件柜' }); // 添加必填的文件上传控件 var fileUploadField = uploadForm.addField({ id: 'custpage_local_upload_file', type: serverWidget.FieldType.FILE, label: '选择要上传的本地文件' }); fileUploadField.isMandatory = true; // 加个提交按钮 uploadForm.addSubmitButton({ label: '确认上传' }); // 把表单返回给用户浏览器 context.response.writePage(uploadForm); } else { // 处理用户提交的文件 var submittedFile = context.request.files.custpage_local_upload_file; if (!submittedFile) { context.response.write('请先选择要上传的文件,返回重试~'); return; } try { // 把文件存到指定的文件柜文件夹里,记得替换folder的ID! var savedFileId = file.create({ name: submittedFile.name, fileType: submittedFile.fileType, contents: submittedFile.getContents(), folder: 123, // 替换成你的目标文件夹内部ID isOnline: true // 设置文件是否可在线访问 }).save(); log.debug('文件上传成功', `已保存的文件ID:${savedFileId}`); context.response.write(`上传成功!文件ID:${savedFileId}`); } catch (err) { log.error('上传失败', err.message); context.response.write(`上传出错了:${err.message}`); } } } return { onRequest: onRequest }; });
2. 部署与使用
- 在NetSuite里创建新的Suitelet脚本记录,上传上面的代码,填好名称和ID。
- 部署脚本时,给需要使用的角色分配该Suitelet的执行权限和文件柜的读写权限。
- 访问Suitelet的URL(部署后会生成),就能看到上传表单,选文件提交就搞定了。
方案二:客户端脚本 + RESTlet(适合自定义页面集成)
如果要在自定义记录页面、仪表板这类地方加个上传按钮,就用这种方式——客户端脚本触发文件选择,把文件转成base64传给RESTlet,再由RESTlet存到文件柜。
1. 编写RESTlet服务器脚本
负责接收客户端传来的文件数据,处理并保存到文件柜:
/** * @NApiVersion 2.x * @NScriptType Restlet */ define(['N/file', 'N/log'], function(file, log) { function post(fileData) { try { // 解析客户端传过来的文件名、类型、base64内容 var { fileName, fileType, fileContent } = fileData; // 创建文件并保存到目标文件夹 var savedFileId = file.create({ name: fileName, fileType: fileType, contents: fileContent, folder: 123, // 替换成你的目标文件夹ID isOnline: true }).save(); log.debug('RESTlet上传成功', `文件ID:${savedFileId}`); return { success: true, fileId: savedFileId }; } catch (err) { log.error('RESTlet上传失败', err.message); return { success: false, errorMsg: err.message }; } } return { post: post }; });
2. 编写客户端脚本
给页面加个上传按钮,处理文件选择、转base64、调用RESTlet的逻辑:
/** * @NApiVersion 2.x * @NScriptType ClientScript */ define(['N/ui/dialog', 'N/https'], function(dialog, https) { function pageInit(context) { // 在当前页面(比如自定义记录页面)添加上传按钮 var currentRec = context.currentRecord; currentRec.addButton({ id: 'custpage_custom_upload_btn', label: '上传本地文件到文件柜', functionName: 'handleLocalFileUpload' }); } // 按钮点击触发的全局函数 window.handleLocalFileUpload = function() { // 创建隐藏的文件选择框 var fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.style.display = 'none'; // 用户选完文件后的处理 fileInput.onchange = function(e) { var selectedFile = e.target.files[0]; if (!selectedFile) return; // 把文件转成base64格式 var reader = new FileReader(); reader.onload = function(loadEvent) { // 去掉base64前缀(比如"data:image/png;base64,") var pureBase64 = loadEvent.target.result.split(',')[1]; // 替换成你部署的RESTlet URL var restletUrl = 'https://你的账号ID.app.netsuite.com/app/site/hosting/restlet.nl?script=456&deploy=1'; // 发送请求到RESTlet var response = https.post({ url: restletUrl, body: { fileName: selectedFile.name, fileType: mapMimeTypeToNetSuiteType(selectedFile.type), fileContent: pureBase64 } }); var resData = JSON.parse(response.body); if (resData.success) { dialog.alert({ title: '上传成功', message: `文件已存入文件柜,ID:${resData.fileId}` }); } else { dialog.alert({ title: '上传失败', message: resData.errorMsg }); } }; reader.readAsDataURL(selectedFile); }; // 触发文件选择框 document.body.appendChild(fileInput); fileInput.click(); document.body.removeChild(fileInput); }; // 辅助函数:把浏览器的MIME类型转成NetSuite的fileType枚举 function mapMimeTypeToNetSuiteType(mimeType) { switch(mimeType) { case 'text/plain': return file.Type.PLAINTEXT; case 'application/pdf': return file.Type.PDF; case 'image/png': return file.Type.PNGIMAGE; case 'image/jpeg': return file.Type.JPGIMAGE; case 'application/vnd.ms-excel': case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': return file.Type.EXCEL; // 其他类型自己按需加 default: return file.Type.PLAINTEXT; } } return { pageInit: pageInit }; });
3. 部署与配置
- 先部署RESTlet,记录下它的URL(包含script和deploy参数),给角色分配权限。
- 部署客户端脚本,关联到你需要添加上传按钮的页面(比如自定义记录),确保角色有该客户端脚本的执行权限。
- 同样要保证角色有文件柜的读写权限。
必看注意事项
- 文件夹ID别填错:去NetSuite文件柜里看目标文件夹的URL,里面的
folder=xxx就是你要的ID。 - 权限一定要配全:执行脚本的角色必须有对应Suitelet/RESTlet的执行权限,以及文件柜的读写权限,不然会报错。
- 文件类型映射:如果要上传特殊格式的文件,记得在
mapMimeTypeToNetSuiteType里补充对应的映射关系。 - 文件大小限制:NetSuite默认上传上限是100MB,要是传更大的文件,得联系NetSuite支持调整。
内容的提问来源于stack exchange,提问作者amit biswas
相关产品推荐
相关产品推荐

