Script to Batch Export Numbers Files

I’m new to AppleScripting and trying to cobble together some functional code from a few different sources, and would love some help troubleshooting.

I have a big directory structure of *.numbers files that I’d like to archive for some colleagues that may not have access to macs and/or Numbers at some future date. What I’d like to do is automate a process that will crawl through that folder structure, and any time it finds a numbers file, export it to both PDF and XLS, and leave it in the same folder as the original file.

The approach I was planning to take was to use Hazel to crawl through the directory and find the proper files, then run an AppleScript to do the exporting. I cobbled together the script below, but am running into errors running the script. Right now I’m getting a class error when I try to set XLStargetFileHFSPath.

The code also includes a line at the top explicitly listing a sample file so I could debug the code before running it through Hazel - I was planning to comment that out when everything was in working order.

Appreciate any help.

property theFile : alias POSIX file "/Users/MacBookAir/test.numbers"
hazelProcessFile(theFile)

on hazelProcessFile(theFile)
	
	tell application "Finder"
		set documentName to the name of theFile
	end tell
	
	if documentName ends with ".numbers" then set documentName to text 1 thru -9 of documentName
	
	tell application "Finder"
		set XLSExportFileName to documentName & ".xls"
		set PDFExportFileName to documentName & ".pdf"
		set folderPath to container of (theFile as alias)
	end tell
	
	set the XLStargetFileHFSPath to folderPath & XLSExportFileName
	
	set the PDFtargetFileHFSPath to folderPath & PDFExportFileName
	
	tell application "Numbers"
		activate
		export theFile to file XLSExportFileName as Microsoft Excel
		export theFile to file PDFExportFileName as PDF
	end tell
	
end hazelProcessFile

There are a few problems.

An Applescript Alias is a reference to the file. You can’t append text to a reference.

Instead of:

set folderPath to container of (theFile as alias)

If you want to manipulate a path as text, you want:

set folderPath to (container of theFile) as text

Applescript also checks for the existence of a file when you set an alias, so they are no good for use to build paths for files that don’t exist yet.

Then you’re feeding Numbers the file alias for the export command, but the export command in Numbers wants a Numbers document reference as an argument, not a file reference.

For instance:

tell application "Numbers"
	set docReference to the front document
end tell

now “docReference” is a reference to a Numbers document.

So you want to open the document in Numbers with the alias you get, then tell it to perform the exports.

Also, you build the save paths as “XLStargetFileHFSPath” & “PDFtargetFileHFSPath” but then you don’t use those, you’re trying to perform the save with “XLSExportFileName” & “PDFExportFileName.”

I don’t have numbers to test, but I think this should work, or at least get you closer:

property theFile : alias POSIX file "/Volumes/Hackintosh HD/Users/work/Downloads/Test.numbers"

hazelProcessFile(theFile)

on hazelProcessFile(theFile)
	
	tell application "Finder"
		set documentName to the name of theFile
		
		if documentName ends with ".numbers" then set documentName to text 1 thru -9 of documentName
		
		set XLSExportFileName to documentName & ".xls"
		set PDFExportFileName to documentName & ".pdf"
		set folderPath to (container of theFile) as text
		
		set the XLStargetFileHFSPath to folderPath & XLSExportFileName
		set the PDFtargetFileHFSPath to folderPath & PDFExportFileName
	end tell
	
	
	tell application "Numbers"
		activate
		set docRef to open theFile
		export docRef to file XLStargetFileHFSPath as Microsoft Excel
		export docRef to file PDFtargetFileHFSPath as PDF
	end tell
	
end hazelProcessFile

That help was much appreciated, t.spoon. That has definitely got me much farther along.

Now when I run your version of the script, I get an error reading: error “Numbers got an error: The document “test” could not be exported as “test”. You don’t have permission.” number 6

As best as I can tell, I have read/write permissions on the folder I’m working in. Is there something silly I’m overlooking?

Edit as :

tell application "Numbers"
	activate
	set docRef to open theFile
	set XLStargetFileHFSPath to XLStargetFileHFSPath as «class furl»
	close access (open for access XLStargetFileHFSPath) # Required for 10.12 thru 10.12.3. Don't hurt with 10.12.4 & 5
	export docRef to XLStargetFileHFSPath as Microsoft Excel
	set PDFtargetFileHFSPath to PDFtargetFileHFSPath as «class furl»
	close access (open for access PDFtargetFileHFSPath) # Required for 10.12 thru 10.12.3. Don't hurt with 10.12.4 & 5
	export docRef to file PDFtargetFileHFSPath as PDF
end tell

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) mercredi 12 avril 2017 20:53:31

Beautiful. Thank you so much, Yvan and t.spoon. It works like a charm.

I’m pasting in the final complete script as a reference if its useful for anyone. (I also threw in a close command so I don’t end up with tons of open files while this is running.)

property theFile : alias POSIX file "/Users/MacBookAir/test.numbers"

hazelProcessFile(theFile)

on hazelProcessFile(theFile)
	
	tell application "Finder"
		set documentName to the name of theFile
		
		if documentName ends with ".numbers" then set documentName to text 1 thru -9 of documentName
		
		set XLSExportFileName to documentName & ".xls"
		set PDFExportFileName to documentName & ".pdf"
		set folderPath to (container of theFile) as text
		
		set the XLStargetFileHFSPath to folderPath & XLSExportFileName
		set the PDFtargetFileHFSPath to folderPath & PDFExportFileName
	end tell
	
	
	tell application "Numbers"
		activate
		set docRef to open theFile
		set XLStargetFileHFSPath to XLStargetFileHFSPath as «class furl»
		close access (open for access XLStargetFileHFSPath) # Required for 10.12 thru 10.12.3. Don't hurt with 10.12.4 & 5
		export docRef to XLStargetFileHFSPath as Microsoft Excel
		set PDFtargetFileHFSPath to PDFtargetFileHFSPath as «class furl»
		close access (open for access PDFtargetFileHFSPath) # Required for 10.12 thru 10.12.3. Don't hurt with 10.12.4 & 5
		export docRef to file PDFtargetFileHFSPath as PDF
		close docRef without saving
	end tell
	
end hazelProcessFile

Thanks for the feedback.
You were facing a problem which I’m well aware of. I reported it to Apple when 10.12.4 was in beta test process.

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) mercredi 12 avril 2017 21:14:55

When an application needs to export a document, I logically expect that the script will be able to export to files that do not exist before running the script.

None of the solutions suggested above worked for me. On the net I found the same thing, marked with the “SOLVED” bird. That is, I ran into some kind of impregnable wall of the Numbers application.

I was worn out like in a bath, but still, it seems to me, I have achieved my goal. It would be nice if someone tested it on their system:


-- Script: Batch Export Numbers Document

set destinationFolder to (path to desktop) as text

tell application "Numbers"
	set docName to name of document 1
	set CSVExportFileName to destinationFolder & docName & "_Exported:" & docName & ".csv"
	set XLSExportFileName to destinationFolder & docName & "_Exported:" & docName & ".xls"
	set numbersExportFileName to destinationFolder & docName & "_Exported:" & docName & ".numbers"
	set PDFExportFileName to destinationFolder & docName & "_Exported:" & docName & ".pdf"
end tell

tell application "Finder"
	try
		set theFolder to make new folder at destinationFolder with properties {name:(docName & "_Exported")}
	on error
		set theFolder to folder (destinationFolder & docName & "_Exported")
	end try
	try -- the most important piece (block) of code
		make new file at theFolder with properties {name:(docName & ".csv")}
		make new file at theFolder with properties {name:(docName & ".xls")}
		make new file at theFolder with properties {name:(docName & ".numbers")}
		make new file at theFolder with properties {name:(docName & ".pdf")}
	end try
end tell

tell application "Numbers"
	activate
	export document 1 to file CSVExportFileName as CSV
	export document 1 to file XLSExportFileName as Microsoft Excel
	export document 1 to file numbersExportFileName as Numbers 09
	export document 1 to file PDFExportFileName as PDF
end tell