soql-lib icon indicating copy to clipboard operation
soql-lib copied to clipboard

Idea for new feature. SOQL to CSV.

Open PawelWozniak opened this issue 6 months ago • 0 comments

Hi. I am trying to create my implementation of SOQL to CSV and currently struggling with some issues like mixed field order or handling of parent and child relations.

Could you try to implement in your lib output conversion to CSV? Such a method should have a separator parameter as it is a comma or semicolon in different countries.

In my case business requirement is to make a report from surveys where we use text fields with 10000 characters in length. Bussines found that in such case field in report is truncated to 255 characters. According to SF documentation, this is expected behavior https://help.salesforce.com/s/articleView?id=000389623&type=1 . They want to have a report with full text field values.

My current implementation is below so you can understand what I am talking about.

    public static String queryToCSV (List<sObject> records, String delimiter) {
        String newLine = '\r\n';

        List<String> allCSVRows = new List<String>();
        Set<String> fieldNames = new Set<String>();
        List<Map<String, Object>> listOfRecords = new List<Map<String, Object>>(); // List of single records represented by Map<FieldAPIName, FieldValue>

        // Extract data from records list
        for (sObject record : records) {
            Map<String, Object> oneRecordFieldValuesMap = record.getPopulatedFieldsAsMap();
            listOfRecords.add(oneRecordFieldValuesMap);
            fieldNames.addAll(oneRecordFieldValuesMap.keySet());
        }

        List<String> tempRow = new List<String>();

        // Build CSV header
        for (String fieldName : fieldNames) {
            tempRow.add(fieldName.escapeCSV());
        }

        allCSVRows.add(String.join(tempRow, delimiter));

        // Add data rows
        for (Map<String, Object> valuesFromRecord : listOfRecords) {
            tempRow.clear();

            for (String fieldName : fieldNames) {
                Object value = valuesFromRecord.get(fieldName);

                if (value == null) {
                    value = '';
                }

                tempRow.add(('' + value).escapeCSV());
            }

            allCSVRows.add(String.join(tempRow, delimiter));
        }

        // Stick all rows together
        String finalCsv = String.join(allCSVRows, newLine);
        allCSVRows.clear(); // free heap

        return finalCsv;
    }

PawelWozniak avatar Aug 05 '24 15:08 PawelWozniak