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

能否用APEX类将Flask API的CSV数据导入Salesforce自定义对象?

用APEX类导入Flask API返回的CSV数据到Salesforce自定义对象

我想确认是否可以通过APEX类将Flask API暴露的CSV数据导入Salesforce自定义对象。我知道APEX类可以发起Web请求调用Flask API,现在希望用同一个类把API返回的CSV数据导入自定义对象,最终能在自定义对象中看到导入的记录。我尝试了以下代码,但CSV数据处理部分需要帮助:

public class CSVImport {
    public static void importCSVFromFlask() {

        // 发起Flask API请求
        HttpRequest request = new HttpRequest();
        request.setEndpoint('My exposed Flask endpoint IP'); // Flask端点
        request.setMethod('GET');
        HttpResponse response = new Http().send(request); // 这部分代码执行正常

        if (response.getStatusCode() == 200) {

            // 这里需要帮助,或许我应该彻底修改代码:
            List<String> csvLines = response.getBody().split('\n');

            // 不想导入CSV的第一行表头
            if (!csvLines.isEmpty() && csvLines.size() > 1) {
                csvLines.remove(0);
            }

            // 创建自定义对象记录
            List<Salesforce_custom_object__c> recordsToInsert = new List<Salesforce_custom_object__c>();

            for (String csvLine : csvLines) {
                List<String> csvFields = csvLine.split(',');

                if (csvFields.size() >= 3) { // 我的CSV只有3个字段
                    Salesforce_custom_object__c obj = new Salesforce_custom_object__c();

                    // 只想导入CSV第二行及以后的第三列数据
                    obj.PriceField__c = Decimal.valueOf(csvFields[2]);
                    recordsToInsert.add(obj);
                }
            }

            // 插入记录到Salesforce
            if (!recordsToInsert.isEmpty()) {
                insert recordsToInsert;
            }
        }
    }
}

优化后的CSV处理方案

原代码的核心问题是直接用split(',')解析CSV不够严谨(比如字段值含逗号时会拆分错误),且缺乏异常处理和边界情况判断。以下是优化后的完整代码:

public class CSVImport {
    public static void importCSVFromFlask() {
        // 发起Flask API请求
        HttpRequest request = new HttpRequest();
        request.setEndpoint('My exposed Flask endpoint IP'); // 替换为你的Flask端点
        request.setMethod('GET');
        
        HttpResponse response = new Http().send(request);
        
        if (response.getStatusCode() == 200) {
            String csvContent = response.getBody().trim();
            if (String.isBlank(csvContent)) {
                System.debug('CSV内容为空');
                return;
            }
            
            // 拆分CSV行并过滤空行
            List<String> csvLines = new List<String>();
            for (String line : csvContent.split('\n')) {
                String trimmedLine = line.trim();
                if (!String.isBlank(trimmedLine)) {
                    csvLines.add(trimmedLine);
                }
            }
            
            // 移除表头行(确保存在数据行)
            if (csvLines.size() > 1) {
                csvLines.remove(0);
            } else {
                System.debug('CSV仅包含表头,无有效数据行');
                return;
            }
            
            List<Salesforce_custom_object__c> recordsToInsert = new List<Salesforce_custom_object__c>();
            
            for (String csvLine : csvLines) {
                // 解析CSV行,支持带引号的含逗号字段
                List<String> csvFields = parseCSVLine(csvLine);
                
                // 确保字段数量满足要求
                if (csvFields.size() >= 3) {
                    String priceStr = csvFields[2].trim();
                    if (!String.isBlank(priceStr)) {
                        try {
                            Salesforce_custom_object__c obj = new Salesforce_custom_object__c();
                            obj.PriceField__c = Decimal.valueOf(priceStr);
                            recordsToInsert.add(obj);
                        } catch (Exception e) {
                            System.debug('解析价格字段失败,行内容:' + csvLine + ',错误信息:' + e.getMessage());
                        }
                    } else {
                        System.debug('价格字段为空,跳过该行:' + csvLine);
                    }
                } else {
                    System.debug('字段数量不足,跳过该行:' + csvLine);
                }
            }
            
            // 批量插入记录并捕获异常
            if (!recordsToInsert.isEmpty()) {
                try {
                    insert recordsToInsert;
                    System.debug('成功插入' + recordsToInsert.size() + '条记录');
                } catch (DmlException e) {
                    System.debug('插入记录失败,错误信息:' + e.getMessage());
                }
            } else {
                System.debug('无有效记录可插入');
            }
        } else {
            System.debug('API请求失败,状态码:' + response.getStatusCode() + ',响应内容:' + response.getBody());
        }
    }
    
    // 辅助方法:解析单个CSV行,处理带引号的特殊字段
    private static List<String> parseCSVLine(String line) {
        List<String> fields = new List<String>();
        Boolean inQuotes = false;
        StringBuilder currentField = new StringBuilder();
        
        for (Integer i = 0; i < line.length(); i++) {
            Character c = line.charAt(i);
            
            if (c == '"') {
                inQuotes = !inQuotes;
            } else if (c == ',' && !inQuotes) {
                fields.add(currentField.toString());
                currentField = new StringBuilder();
            } else {
                currentField.append(c);
            }
        }
        
        // 添加最后一个字段
        fields.add(currentField.toString());
        return fields;
    }
}

关键优化点说明

  • 可靠的CSV解析:新增parseCSVLine方法,支持解析带引号的含逗号字段,避免拆分错误。
  • 边界处理:过滤空行、空内容,防止空指针异常;判断表头后是否存在数据行。
  • 异常捕获:捕获价格字段解析失败、DML插入失败的异常,输出详细日志便于排查。
  • 数据清洗:对字段值做trim处理,避免空格导致的解析错误。

内容的提问来源于stack exchange,提问作者Jeremiah Lethoba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:42:41