All guides

The Salesforce report CSV: the copyright footer, totals rows, and 15- versus 18-character IDs

Export Details from a Salesforce report gives a CSV with the headings, the rows, then a blank line and a footer — a confidentiality notice, a copyright line and the report name — and, when the report shows totals, a grand totals row before that. Every reader takes the footer as more data. Filtering to the rows where the record ID is filled drops all of it, and the IDs themselves need a word: reports show them fifteen characters long and case-sensitive, while the API uses eighteen.

What the export looks like

The details export is the closest to a plain table: one row per record, the columns as the report shows them. Under the last row comes a blank line and then the footer lines, which are text in the first column and blank elsewhere; a report with totals adds a row whose first cell reads Grand Totals with the record count in it. The formatted export keeps the report’s groupings and subtotal rows as well, which is fine for reading and wrong for anything that consumes rows.

Dates are written in the exporting user’s locale format, so the same report gives 01/31/2024 to one person and 31/01/2024 to another; multi-select picklists join their values with semicolons; and currency fields may carry the currency code before the amount.

Drop the footer and the totals

Every real row has an ID; none of the footer or totals rows do. The filter tool here keeps the rows where the ID column is not blank, which removes the blank line, the three footer lines and the totals row in one rule, shows the count of rows kept, and downloads them with every value as written.

The health check reports the same thing from the other direction — the footer shows up as rows with a different number of fields — which is a quick way to see whether a file you were sent has already been cleaned.

Matching IDs between files

A Salesforce ID is fifteen characters in a report and eighteen from the API or a data export, and the fifteen-character form is case-sensitive: two records can differ only by the case of one letter. Excel compares text without regard to case, so a lookup on fifteen-character IDs can match the wrong record. The merge tool here matches on the exact text, case and all, and lists the rows that found no match rather than silently pairing the wrong ones.

Merging a fifteen-character file with an eighteen-character one needs the extra three characters, which are a checksum of the first fifteen; the SQL console can compute them, or the report can be re-run with the eighteen-character ID column added.

Questions

What is the "Confidential Information - Do Not Distribute" line in my CSV?
The footer Salesforce writes under every report export, with a copyright line and the report name. It is not data; filter to rows where the ID is filled and it is gone.
Which export should I use, formatted or details?
Details, for anything that will read the rows: it is one row per record with no groupings. Formatted keeps the report’s subtotal rows and layout, which is for reading, not for processing.
Why do IDs from a report not match IDs from an export?
Reports show fifteen-character IDs; exports and the API use eighteen. The first fifteen characters are the same; the last three are a checksum that lets the ID be compared without regard to case.
Why does Excel match the wrong record on an ID?
Fifteen-character IDs are case-sensitive and Excel compares text without regard to case, so IDs that differ only in case look equal to it. The merge tool here compares the exact text.
Why are the dates in the wrong order?
They are in the locale of whoever exported the report — month first for a US user, day first for most others. The health check flags dates it cannot tell apart, and the SQL console can rewrite them once you know which they are.
Is my export uploaded anywhere?
No. Dropping the footer and totals rows happens in this page, on your device, so the records in your Salesforce report are not copied to anyone to be cleaned.