Skip to main content

How to Export All Salesforce Objects and Fields to a CSV File

Updated Add a comment
💬 In plain words: A Salesforce Data Dictionary is an offline spreadsheet (CSV) that maps out your entire database schema—showing every object, field name, data type, and label. Instead of manually clicking through the Object Manager for hours to document your system, you can use Apex scripts, the Tooling API, or the Salesforce CLI to generate this file automatically in seconds.

Whether you are planning a massive data migration, cleaning up years of technical debt, or preparing for a strict compliance audit, you need a clear map of your Salesforce architecture. Gathering this information manually is a painful and error-prone process. Thankfully, Salesforce provides multiple programmatic ways to extract your schema definitions instantly.

Create an object and fields CSV file in Salesforce using Apex

📌 Key Points Summary

  • Creating an offline data dictionary is vital for org cleanups, third-party integrations, and governance audits.
  • Dynamic Apex allows you to build a reusable utility class that emails the CSV dictionary directly to your inbox.
  • The Tooling API offers the fastest modern route by allowing you to query object and field definitions directly using SOQL.
  • Browser extensions like Salesforce Inspector Reloaded make exporting schema a quick, one-click process for Admins.
  • Always run schema exports as a System Administrator to avoid missing fields hidden by Field-Level Security (FLS).

🛠️ Method 1: The Automated Apex Utility Class

For developers who want to generate schema reports automatically (or schedule them), you can use Dynamic Apex. The Schema namespace lets you inspect object tokens and field definitions at runtime. This script filters the objects, builds an RFC-compliant CSV string (escaping commas so your spreadsheet doesn't break), and emails it out.

Step 1: Create the Utility Class (SchemaDictionaryExporter.cls)
public with sharing class SchemaDictionaryExporter {

    public static void generateAndEmailDictionary(String targetNamespace, String recipientEmail) {
        if (String.isBlank(recipientEmail)) {
            throw new IllegalArgumentException('A valid recipient email is required.');
        }

        List<String> csvRows = new List<String>();
        
        // 1. Build the CSV Header
        csvRows.add('Object API Name,Object Label,Field API Name,Field Label,Data Type,Is Custom');

        // 2. Fetch all SObjects
        Map<String, Schema.SObjectType> globalDescribe = Schema.getGlobalDescribe();

        for (String objName : globalDescribe.keySet()) {
            Schema.SObjectType objType = globalDescribe.get(objName);
            Schema.DescribeSObjectResult objDescribe = objType.getDescribe();

            // Filter: Target a specific namespace or just custom objects
            Boolean matchesFilter = false;
            if (String.isNotBlank(targetNamespace)) {
                matchesFilter = objName.startsWithIgnoreCase(targetNamespace.toLowerCase() + '__') && objName.endsWithIgnoreCase('__c');
            } else {
                matchesFilter = objName.endsWithIgnoreCase('__c'); // Default: All Custom Objects
            }

            if (!matchesFilter) continue;

            String objectApi = objDescribe.getName();
            String objectLabel = escapeCsv(objDescribe.getLabel());

            // 3. Inspect fields for the matched object
            Map<String, Schema.SObjectField> fieldsMap = objDescribe.fields.getMap();
            for (String fieldKey : fieldsMap.keySet()) {
                Schema.DescribeFieldResult fieldDescribe = fieldsMap.get(fieldKey).getDescribe();

                csvRows.add(String.format('{0},{1},{2},{3},{4},{5}', new List<String>{
                    objectApi,
                    objectLabel,
                    fieldDescribe.getName(),
                    escapeCsv(fieldDescribe.getLabel()),
                    String.valueOf(fieldDescribe.getType()),
                    String.valueOf(fieldDescribe.isCustom())
                }));
            }
        }

        // 4. Construct CSV File and Email
        String csvContent = String.join(csvRows, '\n');
        Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
        attachment.setFileName('Salesforce_Data_Dictionary_' + DateTime.now().format('yyyyMMdd') + '.csv');
        attachment.setContentType('text/csv');
        attachment.setBody(Blob.valueOf(csvContent));

        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
        email.setToAddresses(new List<String>{ recipientEmail });
        email.setSubject('Salesforce Schema Data Dictionary Export');
        email.setPlainTextBody('Attached is your automatically generated schema report.');
        email.setFileAttachments(new List<Messaging.EmailFileAttachment>{ attachment });

        Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{ email });
    }

    // Helper: Prevent commas inside labels from breaking the CSV columns
    private static String escapeCsv(String value) {
        if (String.isBlank(value)) return '""';
        if (value.contains(',') || value.contains('"') || value.contains('\n')) {
            value = value.replaceAll('"', '""');
            return '"' + value + '"';
        }
        return value;
    }
}

You can then trigger this report anytime from Anonymous Apex via the Developer Console:

// Generate a dictionary of all custom objects and email it
SchemaDictionaryExporter.generateAndEmailDictionary(null, 'admin@yourcompany.com');

⚡ Method 2: The Modern Way (SOQL & Tooling API)

If writing Apex feels like overkill, you can query Salesforce's metadata directly using the Tooling API. Open the Developer Console Query Editor, check the Use Tooling API box at the bottom, and run this simple SOQL query.

Real-Life Example: Tooling API Query
Run this to extract all fields on the Account object. You can copy the results directly into Excel.
SELECT QualifiedApiName, DeveloperName, DataType, Length 
FROM FieldDefinition 
WHERE EntityDefinition.QualifiedApiName = 'Account'

💻 Method 3: The Salesforce CLI (sf)

For modern developers using VS Code, the Salesforce CLI (sf) makes retrieving object metadata incredibly simple right from your terminal.

sf sobject describe --sobject Account

This command returns a detailed JSON structure of the object schema. You can easily pipe this output into a custom Node.js or Python script to parse the JSON into a beautiful CSV file for your stakeholders.

🖱️ Method 4: Free Browser Extensions (No Code)

For Admins who want a purely point-and-click experience, modern browser extensions are a lifesaver.

  • Salesforce Inspector Reloaded: This free Chrome extension is the holy grail for Salesforce professionals. Go to the "Data Export" tab, run the Tooling API query above, and click the "Copy to Excel" button.
  • Salesforce Schema Builder: While native to Salesforce and fantastic for visualizing relationships (ERD), it does not export to CSV cleanly. Stick to data tools for spreadsheet exports.

🚨 Common Developer Traps & Best Practices

⚠ DEVELOPER TRAP: CPU and Heap Limit Crashes
Calling Schema.getGlobalDescribe() across an enterprise org with thousands of custom objects and managed packages can easily crash your code by exceeding the 10,000ms synchronous CPU limit or the 6MB Heap limit. Always filter your Apex exports by namespace or a specific list of objects, or use Batch Apex to chunk the workload.
⚠ SECURITY TRAP: Field-Level Security (FLS) Blind Spots
Both Apex Describes and SOQL Tooling API queries respect the logged-in user's profile permissions. If your profile does not have "Read" access to a specific field, that field will be completely invisible in your export. Always generate your data dictionaries logged in as a System Administrator.
Core Rule: When generating CSVs via Apex, always sanitize field labels. A label like "Address, Line 1" contains a comma that will instantly break your spreadsheet columns unless you wrap the output in escaped double quotes.
🧭 360 Architecture Summary
  • Admins: Use Salesforce Inspector Reloaded & the Tooling API.
  • Developers: Use the sf sobject describe CLI command.
  • Automation: Use Dynamic Apex (Schema.getGlobalDescribe) for scheduled, emailed reports.
  • Best Practice: Regenerate your CSV dictionary after every major sandbox deployment to ensure your documentation matches production.

❓ Frequently Asked Questions (FAQ)

Q: Can I export all fields for all objects at once using the Tooling API?

🎯 Say this: Technically yes, but running an unfiltered query on the FieldDefinition object in a large org will likely timeout or hit governor limits. It is much safer to iterate through specific objects one by one, or use a dedicated AppExchange metadata tool.

Q: Does the native Salesforce "Data Export" tool in Setup include schema data?

Answer: No. The weekly Data Export service only exports the actual record data (the rows/values), not the metadata or schema definitions (the columns/configuration).

Q: Can I extract picklist values into my CSV export?

Answer: Yes! If you are using the Apex method, you can add fieldDescribe.getPicklistValues() to your inner loop and append it to your CSV row. However, be cautious: fields with hundreds of picklist values can make your CSV file incredibly messy and hard to read.

🔗 Follow-Up Question

Q: How can I use this Data Dictionary during a data migration?

Answer: Once you have your CSV, you can add a new column named "Source System Field." This allows you to hand the spreadsheet to a business analyst or external vendor so they can do field-level mapping (e.g., mapping a legacy SAP field to your Salesforce API name) before you ever open Data Loader or MuleSoft. It acts as your blueprint.

Was this article helpful?

Have a question or spotted a mistake? Ask here about this article

Found this guide useful? Buy me a coffee (opens in a new tab)

Comments

Questions, corrections and your own experience are all welcome.