in reply to Re^4: Mail Merge with Word 2007 and Perl
in thread Mail Merge with Word 2007 and Perl

Well, this is a sort of test for an entry level programming job I applied for. The guy sent me two assignments, the first was to do a mail merge with an Excel spreadsheet and a Word document. I accomplished that fairly easily, it had been a while though. Below is the second assignment.

Perl programming:

a. Save the data in the spreadsheet above to a tab delimited file.

b. Save the Word document template above to a PostScript EPS file.

c. Using the PostScript::Simple module, write a Perl script that merges the template with the data from the tab delimited file.

d. I’d like to see the Perl code, input data, EPS file, and the final output.

So, in reading over the documentation for Postscript::Simple it just didn't seem like the right module to do the job, but again, I am not that familiar with Perl and the guy knows this. From what I saw in the forums etc. and Google searches Win32::OLE seemed the best way to come close to what he is looking for, hence my previous post on doing a mail merge in Perl. But, in re-reading his instructions it seems he wanted the template converted to EPS format and THEN merge that with the tab delimited text file. I am assuming this would then produce the merged documents in EPS format also, although I am not altogether sure about this. I hope this makes sense.

Thanks for your replies and advice

Carl

  • Comment on Re^5: Mail Merge with Word 2007 and Perl

Replies are listed 'Best First'.
Re^6: Mail Merge with Word 2007 and Perl
by GrandFather (Saint) on Aug 21, 2014 at 02:37 UTC

    Postscript is a page description scripting language. In one sense it's just text. If you have a PS version of the original Word template and the PS includes place holder text for the merge fields then the job "simply" becomes: use Perl to replace the merge fields in the template PS file with the merge field entries from the input data.

    I've never used PostScript::Simple nor looked at it. However Perl is pretty good at manipulating text files and both the PS and input data files are text so maybe you don't need the module, or maybe the module makes life easier. Kinda sounds like your job to find out :-D.

    Seems to me the exercise isn't about Perl, but is more a test of your programming skills which ought to transcend the specific tools you are asked to use.

    Perl is the programming world's equivalent of English
Re^6: Mail Merge with Word 2007 and Perl
by roboticus (Chancellor) on Aug 21, 2014 at 22:59 UTC

    cmiller2005:

    OK, then, use Win32::OLE to save the document as an .EPS file. The Postscript::Simple module has an importeps method that apparently lets you put an EPS image on the same page. So you can create some postscript with your perl script, then import your template on top of it. I think that ought to work.

    Take a look at the example.pl script that comes with Postscript::Simple, it may give you the push you need.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Hello Again,

      After getting some clarification on what I'm supposed to do I found that I am supposed to use PostScript::Simple only to create the letters from the text file I used previously. This is what I came up with:

      use strict; use warnings; use PostScript::Simple; $|=1; my $file = 'C:\Users\Carl\Documents\AddressMergeTXT.txt'; open (INPUT, $file) or die ("Can't open file"); my $line; my $text; my $p = 1; while (my $newline = <INPUT>) { chomp $newline; my ($firstname, $lastname, $address, $city, $state, $zipcode, $blank1, + $blank2, $blank3, $blank4, $blank5, $blank6, $blank7, $barcode) = sp +lit('\t', $newline); $line = new PostScript::Simple (papersize => "Letter"); $line -> setfont("Arial,Bold", 10); $line -> text (430, 750, "Cogswell Cogs"); $line -> text(430, 740, "2234 W. Dale Ave."); $line -> text (430, 730, "San Antonio, TX. 77450"); $line -> text (430, 720, "722 - 423 - 7260"); $line -> text (40,700, $firstname); $line -> text (80, 700, $lastname); $line -> text (40, 690, $address); $line -> text (40, 680, $city.","); $line -> text (115, 680, $state."."); $line -> text (135, 680, $zipcode); $line -> setfont("USPSIMBStandard", 10); $line -> text (40, 670, $barcode); $line -> setfont("Arial,Bold", 10); $line -> text (40, 620, "Dear ". $firstname . ","); $text = &getLetter; $line -> text (40, 610, $text); $line -> output('C:\Users\Carl\Documents\testdata\file' .$p .'.eps'); $p += 1; } sub getLetter { my $txline; my $letterfile = 'C:\Users\Carl\Documents\NewLetter.txt'; open (INPUT1, $letterfile) or die ("Can't open file"); while ($txline = <INPUT1>) { return $txline; } } close (INPUT); close (INPUT1);

      It works fine, even though the formatting and style probably sucks, up until I try to read in a form letter using the sub getLetter. It only reads in one line and then stops, thus only the first line of the file gets inserted into the letter. Can someone show me what I did wrong and how I can get the whole file loaded into the letter? Also, almost forgot, can someone tell me how to get the loop to skip reading in the headers on the text file? In other words, so the first letter created will not have First Name, Last Name as the recipient?

      As always, any help appreciated

      Carl

        cmiller2005:

        In your getLetter routine, you're only telling it to read the first line. Let's reproduce it here with good indentation:

        sub getLetter { my $txline; my $letterfile = 'C:\Users\Carl\Documents\NewLetter.txt'; open (INPUT1, $letterfile) or die ("Can't open file"); while ($txline = <INPUT1>) { return $txline; } }

        With the indentation cleaned up, the problem becomes obvious: You read a line into $txline, and then immediately return to the caller. You never actually read the rest of the file.

        To fix it, you probably want to collect the entire file and return it as a single text string. You can do it like this:

        sub getLetter { # Let's start the buffer with an empty string to avoid # an "uninitialized" warning message. my $txline = ""; my $letterfile = 'C:\Users\Carl\Documents\NewLetter.txt'; open (INPUT1, $letterfile) or die ("Can't open file"); while (my $line = <INPUT1>) { # Each time we read $line, we want to add it to the # end of $txline $txline = $txline . $line; } # *now* we have all the data we want in $txline, so we # can return it to the caller return $txline; }

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.