People, Giving, Check-Ins and Services all export CSV, and Google Sheets imports CSV, so getting the data out is the easy half. The work is joining the files. Match on Person ID, never on name. And the result is stale the day you finish.
Key points
- Each Planning Center product exports its own CSV; there is no export that spans two products.
- Google Sheets has no Planning Center connector, so the CSV file is the bridge. The import itself takes four clicks.
- Planning Center exports include a Person ID that is unique for each profile, and that ID is the only join key you should trust.
- Exports over 500 rows arrive as an emailed link rather than a download, and viewers and editors need an export permission switched on.
- The finished workbook is accurate for about a day, which is why this turns into a monthly chore instead of a report.
Almost every church I talk to has a version of this workbook. Three tabs, a column of names down the left, and a VLOOKUP somebody wrote in 2023 that nobody wants to touch.
It exists because Planning Center’s reporting stops at the edge of each product, so the moment your question needs two of them, the report you want doesn’t exist and the spreadsheet is the only place the join can happen. Here’s how to do it properly, and where it will fight you.
Which Planning Center products export to CSV?
More of them than people expect, and each one exports only its own data.
| Product | What you can export | Where |
|---|---|---|
| People | The whole database, or any list with the columns you’ve chosen | Actions → Import & export CSV, or the download icon on a list |
| Giving | Donations and donors. “All reports can be printed or exported into a CSV” | Dashboard or the By donation tab → Download |
| Check-Ins | Event reports, the event chart’s underlying numbers, and one person’s full check-in history | Reports tab → CSV, or Export CSV on the chart |
| Services | The people you’ve filtered or selected | People page → Export CSV (scheduler permissions or higher) |
| Groups | The groups list, added in November 2025 | Groups list → export button → emailed link |
Three things to know before you start.
Size changes the mechanics. In People, a list under 500 results downloads immediately; over 500 you request it and Planning Center emails you a link. So a full-database export is a “go make coffee” operation rather than a click.
Export is now a permission. Since January 2025 there’s a Can export CSVs and reports checkbox on viewers and editors, off by default for new users. If your worship director says the export button isn’t there, that’s usually why.
Some things you’d want don’t export. Check-Ins will give you one person’s check-in history across every event, which is useful and completely impractical for four hundred people. That shape is what makes attendance reporting hard. Services’ people reports are described in the help docs as reports you generate and print: built for a clipboard, not a pivot table. And nothing exports two products at once.
How do you export Planning Center data into Google Sheets?
One complete run, answering the question I get asked most: who gives, who attends, and who does one but not the other. Budget an hour the first time.
- Export your spine from People. Build a list of active adults, set the columns to include Person ID, first name, last name and email, then use the download icon. Every other tab hangs off this file.
- Export donations from Giving. The By donation tab, date range set to the same window you’ll use for attendance, filtered by fund if you need it. Download.
- Export attendance from Check-Ins. Open the event, go to the Reports tab, and export a custom report. You need a person column, so the event chart’s own Export CSV (counts by date, no names) is no use here. Open the file and check its shape before going further: you want one row per person per session. If the report has collapsed to one row per person, step 6 will count everyone as present once; run it per session instead and stack the files into one tab, as the attendance post describes. Pick an event where the adults on your spine actually check in. If the only check-in data you have is kids’ ministry, you are measuring households, not donors: the child’s Person ID will never match the parent’s, and step 7 will quietly mark every giving parent as absent. There is no export-based bridge for that, because the household key doesn’t come out of the exports (more below). So either use an event where the adults themselves check in, or keep the two questions apart: a giving list and a families-who-stopped-bringing-kids list, each true on its own, rather than one join that is wrong in the middle.
- Import each file. File → Import → Upload → drag the CSV in → Insert new sheet(s), separator on auto-detect. Rename the tabs
people,giving,checkins, then freeze the header rows and check that amount columns are actually numbers. Currency symbols arrive often enough to make a SUM silently return zero. - Pivot giving by person. Insert → Pivot table on
giving, rows = the donor’s Person ID column (or email, if that’s the key your export carries, the same key you’ll look up on in step 7), values = SUM of amount and COUNTA of date. One row per donor instead of one row per gift. If email is your key, check it is actually unique before you pivot on it: onpeople, add=COUNTIF(email_column, email_cell)>1and filter for TRUE. Every TRUE is two adults sharing one address, usually a couple. An email-keyed pivot would sum their gifts into one row that step 7 then hands to both of them, so both read as donors for the household total and nothing flags it. Those rows can only be answered at household level: either collapse the spine to one row per shared email for the giving question, or take them out of the per-person comparison and handle them by hand. Person ID never has this problem, which is why it comes first. - Pivot check-ins by person. First add a week column to
checkins, using=WEEKNUM(date)&"-"&YEAR(date), because a parent who checks two kids into two rooms has two rows for one Sunday. Then Insert → Pivot table, rows = Person ID, values = COUNTUNIQUE of that week column. One row per person, and a number that actually means “Sundays present”. - Join both back onto the spine. On
people, add two columns andXLOOKUP(orVLOOKUP) into each pivot on the key that pivot was built on: Person ID for check-ins, Person ID or email for giving, matching what you chose in step 5. Leave the raw lookups unwrapped for now: an#N/Aonpeoplemeans either that person did nothing in the window or that their rows are in the export under a key that didn’t match, and you can’t tell which from this side. So check from the other side too. On each pivot, add a column that looks its key up on the spine,=ISNA(XLOOKUP(key, people!key_column, people!key_column)), and filter for TRUE: those are rows of real giving or attendance that belong to nobody on your spine. Only after step 8 wrap the spine lookups inIFNA(...,0), so the people who genuinely gave or attended nothing read as zero. - Read the orphaned pivot rows as work. Those reverse-lookup TRUEs from step 7, pivot rows with no home on the spine, are the honest quality score for the workbook, not the
#N/As onpeople, most of which are simply members who didn’t give or didn’t check in. Each orphan is a missing person or a key that didn’t match: a different email in Giving than in People, a trailing space. Work through them before you wrap anything inIFNAand before you trust step 9, because every orphan is activity that step 9 would otherwise report as a zero against the wrong person. One thing this check cannot catch: a household whose gifts are recorded under one spouse while the check-ins sit under the other. Both keys are on the spine, both lookups succeed, and step 9 will call one of them a giver who never attends and the other an attender who never gives. The workbook answers per person because that is the only shape the exports come in; the household key doesn’t come out of the exports (more below), so before you act on a name in step 9, look at who else shares their household. - Sort by whatever the question was. Gave but hasn’t attended. Attends but has never given. Read both lists as people, not households, for the reason in step 8.
Step 7 is where this either works or quietly produces nonsense.
Why do the exports stop lining up?
Because the exports don’t agree about who a person is.
Person ID is the key you want. Planning Center’s own import documentation is explicit: exports include a Person ID that is unique for each profile, and you can rename that column to remote_id to match records on the way back in. Where a product’s export carries an ID, use it.
Where it doesn’t, use email. Planning Center’s help docs don’t publish the column list for the Giving export, so check yours before writing the lookup rather than assuming. If it carries a donor identifier, join on that. If it only carries name and email, email is your key. Trim both sides with TRIM() first, because a trailing space in one export and not the other is the common way two copies of the same address stop matching (case isn’t the problem: XLOOKUP and COUNTIF are both case-insensitive, so Sarah@ and sarah@ already match), and run the step 5 uniqueness check too, because a shared family address turns a per-person join into a household join without telling you.
Name matching will lie to you. Mike against Michael, a surname that changed last summer, a household that recorded gifts under one spouse in 2024 and the other in 2025. Each produces someone who looks like they stopped giving and didn’t. It’s the most common reason a lapsed-giver list comes back with a large share of it wrong.
The household key doesn’t round-trip. Households are real in Planning Center. There’s a Households tab, lists can pull in household members, and the API exposes households as their own resource. What you don’t get is a household key you can carry between two CSVs: the Household ID you use on import is not saved to the profile, it only exists in the current import. So roll up to households in Planning Center, or in the API. Not in the spreadsheet.
What does the workbook cost you?
Not the hour. The hour is fine. An hour to answer a real question about your church is a bargain.
It’s stale on arrival. The moment the last CSV lands the workbook starts aging. Someone gives on Sunday, three families check in for the first time, a volunteer comes off the rota, and none of it is in there. A month later the numbers are decorative.
So you do it again. That’s the part that doesn’t survive. January is easy, February is fine, and by May the person who built it has a wedding, a camp and a budget cycle behind them, and nobody trusts a four-month-old sheet enough to bring it to a meeting.
It can’t take a follow-up. Present the giving-and-attendance sheet, and someone asks whether that’s worse than last year, or whether it’s different at the 9am. Neither answer is in the workbook. You’re not reading a report, you’re starting a new export.
Nothing happens next. The sheet ends at a list of names. Whether anyone called them lives in somebody’s head, and next time those same names come back looking exactly as untouched as before.
Which is why I’d rather a church ran this properly twice a year than badly every month. If you’re building it by hand, pick the two or three questions that change a decision: who stopped coming, who’s about to. Do those well.
What are the alternatives to exporting by hand?
Three routes, and the right one depends entirely on who’s on staff.
| Route | Effort to set up | Freshness | Breaks when |
|---|---|---|---|
| Manual CSV → Sheets | An hour, repeated | Stale immediately | The person who built it gets busy |
| Apps Script on the API | A weekend for someone technical | As often as you schedule it | That person leaves the church |
| A reporting layer | Minutes to authorize, then a first sync | Refreshed for you | You outgrow what it models |
Sheets formulas and Apps Script
IMPORTDATA won’t reach Planning Center: every request needs credentials, a Personal Access Token’s client ID and secret over HTTP Basic auth, or an OAuth token. And IMPORTDATA takes nothing but a URL, so it has nowhere to put them. Apps Script does work: UrlFetchApp with an Authorization header, on a time-driven trigger, writing into the sheet.
I’ve seen churches run that happily for years. Two things to plan for: the rate limit is 100 requests per 20 seconds per authenticated user, so anything paging through a full donation history has to back off politely, and a Personal Access Token is fine for your own church but explicitly not allowed for integrating with multiple churches. The script your friend wrote for their church is a rewrite, not a copy. There’s more on going the API route properly if that’s the direction you’re heading.
Connector platforms
Zapier, Pipedream and the spreadsheet add-ons all sit on that same API. They’re good at the shape they’re built for: when a new person is created, append a row. They’re weak at the thing you need, which is joined history across products on a stable person key. You end up with a sheet that grows forever and still doesn’t answer the question.
A reporting layer
Sync every product into one place where they share a person key, and the join stops being a spreadsheet job at all. That is the difference between spreadsheets and a reporting layer in one sentence.
What if you want to stop rebuilding it every month?
This is the job Parable does. It reads all eight Planning Center products over OAuth and syncs them nightly into one place where they share a person key, so “who gave last year and hasn’t attended since March” is a question you type rather than a morning you spend. And it answers the same way next month without redoing anything.
If someone on staff thinks in SQL, the warehouse is there too and you can point Google Sheets straight at it. That’s the version of this article I’d rather write: the connection is live, the join already happened, and the spreadsheet is where you format the answer instead of where you assemble it.
None of which is an argument against exporting. Export is the right tool for a one-off question, and Planning Center’s exports are better than most church software gives you.
The tell is repetition. Building a workbook once to answer something specific is good work. Rebuilding the same workbook every month from the same four CSVs, matching the same names by hand, is a standing report that hasn’t been automated yet. And it usually stops being done long before anyone admits it stopped.

