Jump to content

Inserting Multi-page PDF variable graphics


Admin1676454018

Recommended Posts

This sample job shows how multiple variable PDF graphic files, each of an unknown page-count, can be inserted into a FusionPro template as inline graphics into a text frame. This sample includes all sample files and heavily commented JavaScript that shows how this logic is created.

 

To accomodate the varying and unknown page count as well as number of PDF graphics to be inserted in each record, the advanced "Automatic Page Insertion" option in FusionPro is used. This option, also called "Page Overflow" is a function of a variable text frame. Designed initially to accomodate varying text content length, the functionality also allows for multiple graphic file insertions and is a great solution when each data record requires an unknown and possibly extremely variable set of variable graphics.

 

Pay special attention to the variable frame settings especially the size of the frames and the settings in the "Paragraph" dialogue (inside of the variable text editor).

Insert.zip

Link to comment
Share on other sites

  • 7 months later...
I'm not able to get this to work. I'm on a mac, so I changed the path in the "PDF Graphic Insertion Rule" to 'Macintosh HD:Path:". When I compose, all I get is the first page. I don't get the pages that are to be overflowed. I am needing to do a project similar to this -- any suggestions?
Link to comment
Share on other sites

  • 9 months later...

Help!

 

I am trying to get this sample to work on my computer as well. I downloaded the job and changed the path in the script to:

 

'Macintosh HD:Users:kay: Desktop:Avalanche_tests:Insert PDF Graphics Inline: Docs'

 

(There are NO spaces in front of the Ds, but if I type :D here it gives me an emoticon.)

 

 

I can only get the first page of the doc to compose and it is not pulling the PDFs from the folder "Docs".

 

1) Is my path typed incorrectly? I thought on a Mac the separators were colons. But I tried / and \\ also jsut in case.

 

2) Is this the only part of this script that I should need to change to get this to work?

 

 

Thanks for any help. I have a job very similar to this and I feel if I can get THIS sample to work, I can figure out my job as well.

 

 

********************************

I'll paste the original JS here in case that helps:

 

 

//This rule will examine the input data to find a list of PDF files

//that are to be inserted in the template.

 

//Each PDF is of varying and unknown page count. Therefore, this script

//will determine that page count and reference each page in each PDF.

 

//The resulting tagged markup will include the variable <graphic> tag to reference

//the PDF pages and include as inline images in the template.

 

//This text rule in inserted into a large text frame on a Body page. That frame

//is set to Overflow to a frame on an overflow page.

 

 

//First, declare the variables and initiate them with values.

 

FieldName = '';

PDFfileName = '';

pagesInPDF = 0;

markupToReturn = '';

pathToAllPDFs = 'C:\\Work\\Printable\\Insert PDF Graphics Inline\\Docs\\';

pathToPDF = '';

PDFresourceRef = '';

 

 

//There are 3 fields in this sample - Doc1, Doc2, and Doc3. We will loop through

//each field name with a simple for loop. The following variable sets the counter

//for that loop.

//For example, if you have 25 fields instead of 3 with the PDF file names in them,

//such as "Doc1" through "Doc25" you would set the following to 25.

 

FieldsToInspect = 3;

 

 

 

//This is the main loop that parses through all of the fields for a given record.

 

for (fieldCounter = 1; fieldCounter <= FieldsToInspect; fieldCounter++)

{

FieldName = 'Doc' + fieldCounter;

PDFfileName = Field(FieldName);

pathToPDF = pathToAllPDFs + PDFfileName;

 

//Create a new resource that references this

PDFresourceRef = CreateResource(pathToPDF ,'graphic' ,'no');

 

//Find out how many pages it has

pagesInPDF = PDFresourceRef.countPages;

 

//return PDFresourceRef.name;

 

//This is the secondary loop for this script.

//It will loop through and create markup for each page in the PDF.

for (pageLoop = 1; pageLoop <= pagesInPDF; pageLoop++)

{

markupToReturn += '<graphic file="' + PDFresourceRef.name + '" pagenumber = "' + pageLoop + '" position="afterline"/>';

 

markupToReturn += '<P>';

}

 

 

 

 

 

}

 

//remove the last <P>

markupToReturn = Left(markupToReturn, markupToReturn.length - 3);

 

 

return markupToReturn;

 

 

Thanks,

 

KayEll

Link to comment
Share on other sites

Your signature mentions "Windows XP Version 2002," but you're obviously on a Mac. It would be useful to know the exact version of Mac OS X you're running.

 

At any rate, on either platform, you definitely need a trailing directory separator at the end of the path in that particular rule, so that in this line:

pathToPDF = pathToAllPDFs + PDFfileName;

It properly builds the path with the last separator. Otherwise, it's going to build a path such as:

[noparse]'Macintosh HD:Users:kay:Desktop:Avalanche_tests:Insert PDF Graphics Inline:DocsMyGraphicName[/noparse]', which is surely wrong (it should be something like:

[noparse]'Macintosh HD:Users:kay:Desktop:Avalanche_tests:Insert PDF Graphics Inline:Docs[/noparse]:MyGraphicName' - note the difference that last colon makes).

 

So, I would try adding a single colon at the end of the path specification:

[noparse]'Macintosh HD:Users:kay:Desktop:Avalanche_tests:Insert PDF Graphics Inline:Docs[/noparse]:'

 

If that still doesn't work (or even if it does), you probably should be using the newer POSIX-style paths on Mac instead of the old-style HFS paths. So I would try a path like this:

'/Users/kay/Desktop/Avalanche_tests/Insert PDF Graphics Inline/Docs/'

Note the trailing slash at the end.

Link to comment
Share on other sites

Dan, Yes I very recently moved my FP to my Mac and forgot to update my signature. I am using OS X 10.5.8, FP Desktop 6.0P, and Acrobat 9.

 

Thanks for the tip, your fix worked perfectly! I didn't realize I needed that last separator.

 

I also didn't have my text boxes extending all the way to the edge of the PDF, so that was another problem.

 

So, I have this sample working now, and my sample as well after I renamed all my PDFs to Doc1 and Doc2, but I think my eventual data and PDFs will be coming to me in a different manner. My fields will have the different document names as the header (ie: Kitchen, Bath, Bedroom) and the value will simply be a yes or a no if they require that document. They can have 1, 2 or all 8 documents if they desire. I'm not 100% sure how I will need to alter this to fit that. Or if I should just have them make their data fit this existing script. I can probably have them send me the data however I want.

 

Thanks for your help! Much appreciated.

KayEll

Link to comment
Share on other sites

  • 4 months later...
I can't seem to get it to work either, and have tried every variation that I can think of for the path.

 

pathToAllPDFs = 'C:\Documents and Settings\ehigginbotham\Desktop\Insert PDF Graphics Inline\Docs:';

Whenever you're having a problem like this, it helps to do a very basic bit of debugging. If you simply add a line like this to your rule:

Print(pathToAllPDFs);

And then do a composition and look in the log (.msg) file, it should become immediately obvious what the problem is. Or you can just add this line temporarily while you're in the Rule Editor and click Validate:

return pathToAllPDFs;

I'll bet that it returns this: [noparse]"C:Documents and SettingsehigginbothamDesktopInsert PDF Graphics InlineDocs:".[/noparse] So that's obviously not right.

 

Why do all the backslashes get removed? Because the backslash is a special character in string literals in JavaScript:

https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Values%2c_Variables%2c_and_Literals#Escaping_Characters

 

You can work around this in several ways, which I'll present in order from least to most recommended:

 

  1. As in the sample, double up all backslashes to "escape" them, that is, to let the JavaScript interpreter know that they're literal backslash characters and not modifiers for the characters following them, like so:
    pathToAllPDFs = 'C:\\Documents and Settings\\ehigginbotham\\Desktop\\Insert  PDF Graphics Inline\\Docs\\';


  2. Replace the backslashes with forward slashes, like so:
    pathToAllPDFs = 'C:/Documents and  Settings/ehigginbotham/Desktop/Insert  PDF Graphics Inline/Docs/';

    All modern versions of Windows allow forward slashes in place of back slashes in file paths. (The only exception is at the beginning of a UNC path such as "\\server\share\filename".)

  3. Don't specify a path in the JavaScript code at all, and specify a Search Path for the job instead. Change the line in the rule to this:
    pathToAllPDFs = "";

    And then go into the Composition Settings dialog, on the Advanced tab, and enter the path in its normal format (with single backslashes, or you can use forward slashes) in the Search Path box. The call to CreateResource will automatically look for the graphics along the specified Search Path. This is much more forgiving than doing it in code because you don't have to worry about the trailing slash, and if you have multiple rules and change the location of your graphic resources, or run the job on a different machine, you can simply change the single search path setting for the job. You can also include multiple search path locations by delimiting them with semicolons and all those paths will be searched.

Link to comment
Share on other sites

I had figured out the / instead of \ thing through luck. lol I am actually using this rule for a template in marcom central, do you know if the 3rd option will work if the paths to the images are on the web? I know this is actually a question for that forum, but this rule was so similar I started here.

 

thanks for your help

Link to comment
Share on other sites

I had figured out the / instead of \ thing through luck.

Luck is fine, but debugging is better. Thus my suggestion to use Print and return statements to find out what's really going on in different places in your rules.

lol I am actually using this rule for a template in marcom central, do you know if the 3rd option will work if the paths to the images are on the web? I know this is actually a question for that forum, but this rule was so similar I started here.

If you're in the MarcomCentral environment, then the Search Path is set up automatically in the composition to point to the locations of the files you upload through the Manager to your image libraries. So you don't need to specify the path anywhere from your end for any online compositions. You'll still need the path for offline compositions and Previews on your local machine, though.

Link to comment
Share on other sites

Now that this rule is working, I need to use it in conjunction with a rule that will make the total page count of a book divisable by 4. Here is the rule I have so far. Any suggestions.

 

//Letter Page

if ((Field("ZIP")) == "")

{

FusionPro.Composition.SetBodyPageUsage("Directory file",false);

}else{

FusionPro.Composition.SetBodyPageUsage("Directory file",true);

}

 

if (Field("Page 1 y or n") == "y")

{

FusionPro.Composition.SetBodyPageUsage("70",true);

}else{

FusionPro.Composition.SetBodyPageUsage("70",false);

}

if (Field("Page 2 y or n") == "y")

{

FusionPro.Composition.SetBodyPageUsage("71",true);

}else{

FusionPro.Composition.SetBodyPageUsage("71",false);

}

 

if (Field("Page 3 y or n") == "y")

{

FusionPro.Composition.SetBodyPageUsage("72",true);

}else{

FusionPro.Composition.SetBodyPageUsage("72",false);

}

 

// place each field into an array

// then count the number of pages in each pdf and add them together

//if there are any static pages in the booklet

// adjust the starting number of the PAGECount here.

// since we have no static pages in this booklet, keep the PAGECount at 0

 

var PAGECount=86;

var PicPages=4;

PAGEArray = [ Field("ZIP"),Field("Page 1 y or n"),Field("Page 2 y or n"),Field("Page 3 y or n") ]

 

for (i = 0 ; i < PAGEArray.length ; i++)

{

if (PAGEArray != "")

{

var Pic = new FusionProResource(PAGEArray, "graphic", "true");

PicPages = Pic.countPages;

PAGECount+=PicPages;

}

 

}

 

//divide pagecount + 10 by 4

//if remainder is 1, you will need all 3 blank pages

//if remainder is 2, you will need 2 blank pages

//if remainder is 3, you will need 1 blank page

if (PAGECount % 4 == 1)

{

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 1", "true");

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 2", "true");

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 3", "true");

}

 

else if (PAGECount % 4 == 2)

{

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 1", "true");

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 2", "true");

}

 

else if (PAGECount % 4 == 3)

{

FusionPro.Composition.SetBodyPageUsage("Intentional Blank 1", "true");

}

Link to comment
Share on other sites

  • 3 months later...
I am using this template quite often. This job I am working on includes multiple pdfs that we are combining that are kits. I have a kit number in my database that I would like to print on the very last page of all the PDF's I insert. Is there a way to do this with this template? I tried added a text box to the overflow page and every page but the first page has the kit number that I added. This will not work. I need onlly the last page to have the kit number.
Link to comment
Share on other sites

I am using this template quite often. This job I am working on includes multiple pdfs that we are combining that are kits. I have a kit number in my database that I would like to print on the very last page of all the PDF's I insert. Is there a way to do this with this template? I tried added a text box to the overflow page and every page but the first page has the kit number that I added. This will not work. I need onlly the last page to have the kit number.

Yes, this could be done with some changes to the sample template. Instead of simply adding the <graphic> tags to the markup for the overflow pages, you could use an FPRepeatableComponent to call out a Template Page, which could have multiple frames on it: one Graphic frame to hold the page, and one Text frame to show your kit number, which you would only set on the last page of each PDF (when pageLoop == pagesInPDF in the rule). I don't have the time to actually set this up right now, but maybe someone else can pick up the ball and run with it.

Link to comment
Share on other sites

  • 1 month later...
So I am a huge novice in the javascript writing. I downloaded the zip file to try and see if I could get your template to work. From what I can tell all I should need to do to get your template to work correctly is change the "pathtoallPDFs" location correct. I tried this and the expression is OK but doesn't return anything.
Link to comment
Share on other sites

So I am a huge novice in the javascript writing. I downloaded the zip file to try and see if I could get your template to work. From what I can tell all I should need to do to get your template to work correctly is change the "pathtoallPDFs" location correct. I tried this and the expression is OK but doesn't return anything.

If it's not returning anything, then you don't have the path right. If it's got any backslashes, try using forward slashes instead.

Link to comment
Share on other sites

  • 2 weeks later...

So, I'm using the template you provided and I get the graphics in great. The problem is I want to put and address block and a 2D barcode on the second page, but my text boxes are resulting in nothing. I have 14,000 pdfs and they are all 2 pagers so if there is a different way to pull in the PDFs as two pagers instead of having to seperate them all into two pagers and having a front page and back page rule I can try that. Just not sure why with the current multi-page template I can't get any text boxes to return anything.

 

I am running Windows XP with acrobat 8 and FP desktop version 5.1P1d

 

Thanks

Link to comment
Share on other sites

  • 3 months later...

Ok,

 

I got this sample to work, and then with that knowledge applied it to my job.

 

I have a few questions...

 

1) Why is the text box on the overflow page larger than the actual page in acrobat?

2) Why is the box offset (Y coordinate is -.15")?

3) When I print (or distill) the .ps file created all of the landscape pages are correctly imposed to portrait, but they seem to be both offset and stretched, and actually run off the page.

Link to comment
Share on other sites

1) Why is the text box on the overflow page larger than the actual page in acrobat?

Because you're bringing in the page of the external PDF as an inline graphic in a text frame, so it has to basically be typeset like a really large text character. So the text frame has to be slightly larger than the text. Note that the text frame is actually larger than the body page itself, so the output is still 8.5 by 11 inches.

2) Why is the box offset (Y coordinate is -.15")?

I think that's just a glitch in the sample. It can be set to zero and the job will work just fine.

3) When I print (or distill) the .ps file created all of the landscape pages are correctly imposed to portrait, but they seem to be both offset and stretched, and actually run off the page.

I think that's just a matter of getting the printer driver or Distiller settings right. Feel free to send the files to Support for analysis.

Link to comment
Share on other sites

  • 1 year later...

Using this rule to place 8.5 x 11 PDF files that may or may not have .125" bleed. I am getting mixed results as far as the art centering in the text box. I have been using alignh and alignv with mixed results. I also noticed that in the supplied code you use position="afterline". If I remove that the horizontal positioning works perfect, however the art is top aligned in the box. I do not see any documentation on 'position' in the tag reference or user's guide. Any way to just center without scaling regardless of bleed box dimensions? See section of code below.

 

   //This is the secondary loop for this script.
   //It will loop through and create markup for each page in the PDF.
   for (pageLoop = 1; pageLoop <= pagesInPDF; pageLoop++)
   {
       markupToReturn += '<graphic file="' + PDFresourceRef.name + '" pagenumber = "' + pageLoop + '" scale="off" alignh="center" alignv="center" />';

       markupToReturn += '<P>';
   }

Link to comment
Share on other sites

Using this rule to place 8.5 x 11 PDF files that may or may not have .125" bleed. I am getting mixed results as far as the art centering in the text box. I have been using alignh and alignv with mixed results. I also noticed that in the supplied code you use position="afterline". If I remove that the horizontal positioning works perfect, however the art is top aligned in the box. I do not see any documentation on 'position' in the tag reference or user's guide. Any way to just center without scaling regardless of bleed box dimensions? See section of code below.

 

   //This is the secondary loop for this script.
   //It will loop through and create markup for each page in the PDF.
   for (pageLoop = 1; pageLoop <= pagesInPDF; pageLoop++)
   {
       markupToReturn += '<graphic file="' + PDFresourceRef.name + '" pagenumber = "' + pageLoop + '" scale="off" alignh="center" alignv="center" />';

       markupToReturn += '<P>';
   }

You could try specifying a different bounding box, by adding an attribute such as pdfbboxtype="MediaBox". (Valid values are "CropBox" (the default), "MediaBox", "BleedBox", "TrimBox", and "ArtBox".) Without seeing the graphics, I'm not sure exactly what effect it will have, but you could play around with that.

 

Also, the attributes for scale, alignh, and alignv apply only to graphics in graphic frames, and have no effect on inline graphics in text frames, which is what these are.

 

If you know how many pages there are going to be ahead of time, or at least the maximum, then instead of using inline graphics in a text flow and overflow pages, you could specify multiple body pages with graphic frames, which would allow you to utilize all the graphic scaling and alignment options. You could use the FusionPro.Composition.SetBodyPageUsage function to suppress the extra pages in each record. This is a bit more work to set up, but it might be worth it for the scaling options.

Link to comment
Share on other sites

  • 4 weeks later...

@Hadrian,

The only way I could get this to work for my situation was to use a graphic box method instead of the text overflow method. Because my situation had to handle files with bleed and files without bleed, this was my only option as I could not get the overflow method to center properly for all scenarios. I put the following rule in a text rule. I create a graphic box on page 1 called "Front" and another on page 2 called "Back" and I do not assign any rule or variable field to the graphic box, the rule will do that.

 

Here is my code:

 

FieldName = '';
PDFfileName = '';
pagesInPDF = 0;
markupToReturn = '';
pathToAllPDFs = 'Macintosh HD:Users:macuser01:Desktop:resources:'; /* change "pathToAllPDFs" value to the path where your local test files are located /*
pathToPDF = '';
PDFresourceRef = '';

var FrontFrame = FindGraphicFrame("Front");
var BackFrame = FindGraphicFrame("Back");

//This is the main loop that parses through all of the fields for a given record.

PDFfileName = Field("File");
pathToPDF = Field("File");  /* this one should be uncommented for marcom central */

/*pathToPDF = pathToAllPDFs;  //uncomment this and comment out the one above to preview on a local machine  */

//Create a new resource that references this
PDFresourceRef = CreateResource(pathToPDF ,'graphic' ,'no');

//Find out how many pages it has
pagesInPDF = PDFresourceRef.countPages;

//This is the secondary loop for this script.
//It will loop through and create markup for each page in the PDF.
if (Field("Sides")=="1"){
for (pageLoop = 1; pageLoop <= pagesInPDF; pageLoop++)
{
FrontFrame.SetGraphic('<graphic file="' + PDFresourceRef.name + '" pagenumber = "1" scale="off" />');
return pathToPDF;
}
}else if (Field("Sides")=="2"){
for (pageLoop = 1; pageLoop <= pagesInPDF; pageLoop++)
{
FrontFrame.SetGraphic('<graphic file="' + PDFresourceRef.name + '" pagenumber = "1" scale="off" />');
BackFrame.SetGraphic('<graphic file="' + PDFresourceRef.name + '" pagenumber = "2" scale="off" />');
return pathToPDF;
}
}
}
return pathToPDF;

return markupToReturn;�

Hope this helps you!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...