You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问询:如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:19:54