Mail merge
is it possible to mail merge from a Numbers database (names and addresses) to a Pages document eg address labels or envelopes?
iMac 27″, macOS 10.15
is it possible to mail merge from a Numbers database (names and addresses) to a Pages document eg address labels or envelopes?
iMac 27″, macOS 10.15
Pages doesn't have built-in Mail merge but it's quite easy to mail merge to envelopes from Numbers with a short script:
In Pages, File > New and pick the envelope template you want. Delete the "to" placeholder text and replace it with a new Text Box (Insert > Text Box) and style it the way you want, with font size, etc. Make sure it is tall enough to hold the address with the most number of lines. An easy way to do that is simply enter the "tallest" address. It will be replaced with others as the script runs.
In Numbers arrange the data similar to the screenshot, with one Header Row. Each row cell will print on a separate line so have first name and last name combined in one cell, not in separate cells. You can add/insert columns as needed and some cells in the middle (for example the second line of an address) can be blank but make sure there are no blank rows at the bottom. As written the script assumes the data will be in the first table on the first sheet of the frontmost document.
Open Script Editor (in Applications > Utilities), choose Javascript in the dropdown upper left (i.e. change it from the default AppleScript), and copy paste the following script:
var table = Application("Numbers").documents[0].activeSheet.tables[0];
var doc = Application("Pages").documents[0];
var totxt = doc.textItems[0].objectText;
for(var i=1;i<table.rowCount();i++) {
var rowvals = table.rows[i].cells.whose({_not:[{value:null}]}).value().join("\n");
totxt.set(rowvals);
doc.print();
}
With the Pages and Numbers documents open, click the Run button in Script Editor. If "nothing happens" make sure Script Editor is listed and checked at System Preferences > Security & Privacy > Privacy Accessibility.
Test on a short table first to make sure it is doing what you want. Setup should take only a few minutes.
SG
I'm using a template included in Pages (Avery C32011). Each label on this template consisted of a Name/Job title box and an Address box. I have removed the Name/Job title boxes and saved the remaining label with the address boxes as a new template.
As you will see from my screenshot, I have 15 entries on the spreadsheet (all fictitious) and the labels print as far as line 10 'Mary Green', with the error message as shown.
I've just discovered my screenshot is too large so I'll send three separate ones.
southcoast-dweller wrote:
I'm using a template included in Pages (Avery C32011). Each label on this template consisted of a Name/Job title box and an Address box. I have removed the Name/Job title boxes and saved the remaining label with the address boxes as a new template.
My Pages doesn't include an Avery C32011 template. Also it seems that you have altered that template in some way.
Have you tried using the template included in my sample download?
With that template I ran the script using your 14 rows of data with results as expected.
So your results seem to have something to do with the template you have used. Perhaps the script is looking for textboxes that you have removed.
SG
Yes, you are correct. If I run it on the same template without removing any boxes all 14 rows do appear. I haven't yet used your template as I'm not sure how to transfer it to Pages, but I think by resizing the boxes on the one I have tried, it will suit my purpose.
Looks as though with your help I have finally got there!
Many thanks
Fantastic news!
To transfer any document into Pages as a template just open it and File > Save as Template ... and give it a name. It will then be available in the Template Chooser under My Templates.
SG
I got my Avery template for testing here. Many others available in Pages format. No account needed.
This is script I used for testing the order in which the labels print.
const app=Application("Pages"),
doc = app.documents[0],
ti = doc.textItems;
for (i in ti) {ti[i].objectText = i}
It results in something like this:
The properties of a text box look something like this:
When I cut and paste back some boxes, the order changes. But I can't figure out the pattern.
In theory one could reorder by x and y position in some automated way. But that would be work!
SG
Yes, that random ordering of the objectText is what I expected, and I too, saw the properties for the individual objectText item. Some of these properties are read-only like the backgroundFillType. At some point, I may adapt your code to see if I can fill out this form with mischief data from Numbers.
SG
You are welcome.
OK, thanks for that.
Also, you may have more rows in your table than the template has text boxes?
SG
Thanks for all that, I'll peruse over the next few days and let you know how I get on.
That's good, thanks again
Couldn't send the third screen shot, but all it showed were 9 the printed labels
Mail merge