Insert PDF pages help

Insert PDF pages help

DC-MWA
Collaborator Collaborator
2,094 Views
14 Replies
Message 1 of 15

Insert PDF pages help

DC-MWA
Collaborator
Collaborator

Hello,

I have a cool lisp that attaches PDF pages from a selected pdf file.

I have modified it to know the number of pages (using Lee Mac's _PDFPageCount).

It asks the user the height of pages and stacks them using the input.

I'm wondering if there is a way to get each page height and use that information for stacking the inserted pages. The reason is if the pdf file has some 8.5 x 11 pages and some 11 x 8.5 pages, it overlaps some of the pages when stacking.

I have attached the lisp file.

Thanks in advance fo any input and/or assistance received.

-dc

0 Likes
2,095 Views
14 Replies
Replies (14)
Message 2 of 15

ronjonp
Mentor
Mentor

Quickly looking at the code you provided .. it originally used the bounding box to place the PDF's I'd suggest using the version before you modified it and it should work.

0 Likes
Message 3 of 15

CodeDing
Advisor
Advisor

@DC-MWA ,

 

Try this. Did what I could to help out. Update this function in your original lisp file. I will highlight my changes made.

 

The exception, is that now a list with 2 pieces of information will be returned, instead of an integer (Lee's function was already doing all the heavy lifting).

 

Here is updated function:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun _PDFPageCount ( filename / fob fso mat reg cnt str pgs )
  ;; Translation by Lee Mac of the VBScript code by Chanh Ong
  ;; found at http://docs.ongetc.com/?q=content/pdf-pages-counting-using-vb-script
  ;;
  ;; Edits by CodeDing, for user DC-MWA, per help request here:
  ;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/insert-pdf-pages-help/td-p/9890051
  ;;
  ;; Call with fully qualified filename of PDF file:
  ;; (_PDFPageCount "C:\\Folder\\Filename.pdf")
  ;;
  ;; Returns list describing number of pages in specified PDF file and page sizes.
  ;; Return format --> (("PAGE_COUNT" . #) ("PAGE_SIZES" (# #) ...))
 
  (if
    (and
      (setq filename (findfile filename))
      (eq ".PDF" (strcase (vl-filename-extension filename)))
    )
    (vl-catch-all-apply
      (function
        (lambda ( / _ReadAsTextFile _CountPage _GetPageSizes)
          (defun _ReadAsTextFile ( fso fn / fob str res )
            (setq fob (vlax-invoke fso 'getfile fn)
                  str (vlax-invoke fso 'opentextfile fn 1 0)
                  res (vlax-invoke str 'read (vlax-get fob 'size))
            )
            (vlax-invoke str 'close)
            (vlax-release-object str)
            (vlax-release-object fob)
            res
          )
          (defun _CountPage ( rgx str / mat pag )
            (vlax-put-property rgx 'pattern "/Type\\s*/Page[^s]")
            (vlax-put-property rgx 'ignorecase actrue)
            (vlax-put-property rgx 'global actrue)
            (setq mat (vlax-invoke rgx 'execute str)
                  pag (vlax-get mat 'count)
            )
            (vlax-release-object mat)
            (if (zerop pag) 1 pag)             
          )
          (defun _GetPageSizes (str / scale_factor pos lb rb pg pgs)
            ;; scale_factor is based on standard "user space units" (1 unit = 1/72 inch)
            ;; ... as defined by Adobe Portable Document Format (pg 79, "UserUnit"):
            ;; https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf
            (setq scale_factor 72)
            (setq pos 0)
            (while (setq pos (vl-string-search "/MediaBox" str pos))
              (setq lb (+ 2 (vl-string-search "[" str pos))
                    rb (1+ (vl-string-search "]" str lb))
                    pos (1+ pos)
                    pg (substr str lb (- rb lb))
                    pg (cddr (read (strcat "(" pg ")")))
                    pg (mapcar '(lambda (x) (/ x scale_factor)) pg)
                    pgs (cons pg pgs)
              )
            )
            (reverse pgs)
          )
          (setq fso (vlax-create-object "Scripting.FileSystemObject")
                reg (vlax-create-object "VBScript.RegExp")
                str (_ReadAsTextFile fso filename)
                cnt (_CountPage reg str)
                pgs (_GetPageSizes str)
          )
        )
      )
    )
  )
  (foreach obj (list str fob mat fso reg)
    (vl-catch-all-apply 'vlax-release-object (list obj))
  )
  (list (cons "PAGE_COUNT" cnt) (cons "PAGE_SIZES" pgs))
);;end defun _PDFPageCount
(vl-load-com) (princ)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

Here is an example of the returned format (I used a PDF with 2 different page layouts):

(("PAGE_COUNT" . 4) ("PAGE_SIZES" (8.5 14.0) (8.5 14.0) (14.0 8.5) (14.0 8.5)))

 

Best,

~DD

 

0 Likes
Message 4 of 15

CodeDing
Advisor
Advisor

@DC-MWA ,

 

--- SOME NOTES ---

- The "MediaBox" page size retrieval will not work on ALL PDFs, but it should work on most. If the PDF was created by Adobe or Microsoft, I feel pretty confident that it will work.

- The units returned for page size are in INCHES. This is based on the Adobe standard for MediaBox  units (I commented where I found this information in the function I added). So, if you want units other than inches, you can change the "scale_factor" variable appropriately.

 

Best,

~DD

0 Likes
Message 5 of 15

maratovich
Advisor
Advisor

Alternative option, maybe it will help - AutoImportCAD 

---------------------------------------------------------------------
Software development
Automatic creation layouts and viewport. Batch printing drawings from model.
www.kdmsoft.net
0 Likes
Message 6 of 15

DC-MWA
Collaborator
Collaborator

Thanks for taking a look.

The orginal set all insertion points at 11 inches apart

 

(setq ipoint (list (car ipoint) (- (cadr ipoint) 11.0)));;original sets all to 11

0 Likes
Message 7 of 15

DC-MWA
Collaborator
Collaborator

Thank you for your assistance. My lisping skills are minimal at best. I do not know how to take the page size, get the height and feed into the ipoint variable for each page within the while statement.

0 Likes
Message 8 of 15

chriswade
Collaborator
Collaborator

I know that this is from almost a year ago, but seeing as there aren't really any great examples out there, I will leave this here. I have written a routine, it's primary purpose is to insert Title 24 Calculations (PDFs) into CAD drawings to where they won't overlap and will stay within the usable space of a title block. It automatically creates new layouts as needed and even has an option at the end to export all layouts to separate CAD files.

 

You may need to make some minor adjustments for your CAD standards, but it should work with pretty much any multipage PDF file out there.

 

0 Likes
Message 9 of 15

Sea-Haven
Mentor
Mentor

Please don't take this personally but after scrolling numerous pages of code I looked for the movie, so got very uninterested. As a marketing suggestion do the movie 1st next time and just include the code as a attachment. Ex Autocad reseller and State Civil software rep.

 

I know there are a few of us here that don't like having to scroll through numerous pages of code looking for something that pops out. But would hit download and check it out later.

 

Hey Mr autodesk when can we update a post that is more than 30 minutes old ?

0 Likes
Message 10 of 15

chriswade
Collaborator
Collaborator

I don't understand your comment at all, there is no marketing here, there is no movie, just a single command called T24 (which is literally defined at the beginning of the code, no need to scroll at all).

 

This is simply a tool to help the OP do what they requested the ability to do, which I described before the code.

 

I am also just an end user, in no way affiliated with Autodesk or any reseller (other than use a reseller to purchase our software).

 

That being said, I will go ahead and attach a video to this post showing how it works.

 

 

Now, if you are asking how I get the page size, well I cheat, I don't actually get it from the PDF file, instead, the pertinent sections are:

 

 

  (defun LM:ssboundingbox ( sel / idx llp ls1 ls2 obj urp )
    ;; Code by Lee Mac from: http://www.lee-mac.com/ssboundingbox.html
    ;; Selection Set Bounding Box  -  Lee Mac
    ;; Returns a list of the lower-left and upper-right WCS coordinates of a
    ;; rectangular frame bounding all objects in a supplied selection set.
    ;; sel - [sel] Selection set for which to return bounding box
    (repeat (setq idx (sslength sel))
      (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
      (if
        (and 
          (vlax-method-applicable-p obj 'getboundingbox)
          (not
            (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'llp 'urp)))
          );not
        );and
        (setq ls1 (mapcar 'min (vlax-safearray->list llp) (cond (ls1) ((vlax-safearray->list llp))))
              ls2 (mapcar 'max (vlax-safearray->list urp) (cond (ls2) ((vlax-safearray->list urp))))
        );setq
      );if
    );repeat
    (if (and ls1 ls2) (list ls1 ls2))
  );LM:SSBoundingBox

 

 

 

Then you can attach the PDF and get the boundary of the most recently inserted page using the following:

 

 

(setq *Single* nil
      *Single* (ssadd)
      SingleBound (LM:SSBoundingBox *Single*)
      LowerLeft (nth 0 SingleBound)
      UpperRight (nth 1 SingleBound)
      Width (- (car UpperRight) (Car LowerLeft))
      Height (- (cadr LowerLeft) (cadr UpperRight))
);setq
(if (< Width 0)
(setq Width (* Width -1))
)
(if (< Height 0)
(setq Height (* Height -1))
)

 

 

 

This will specifically get you the width and height of the page. I have recently been told that there may be a way to get it from the PDF file itself, but I haven't tried that approach as of yet, as this accounts for the entire outline of the PDF and the other may not.

 

I also updated my previous post to make the code an attachment instead of inline in the reply.

0 Likes
Message 11 of 15

DC-MWA
Collaborator
Collaborator

This is very interesting. Thank you for sharing.

I will do a little more "testing" later, my day is full.

0 Likes
Message 12 of 15

chriswade
Collaborator
Collaborator

You are welcome, now here is a much more robust version that allows you to select the scale, which pages to insert, etc.

0 Likes
Message 13 of 15

DC-MWA
Collaborator
Collaborator

This is pretty cool. It seems like the user should select the sheets desired and the scale should be based on the two points selected.

What do you think?

0 Likes
Message 14 of 15

chriswade
Collaborator
Collaborator

The reason I haven't done that, is the tool automatically creates new layouts to allow for the number of pages at the specified scale, but not a bad idea with an AutoScale function, but this would also mean you would need to specify the number of rows and columns you would want, which would require a bit of rework, when I have the time, I might add that, as I could see it being useful.

0 Likes
Message 15 of 15

DC-MWA
Collaborator
Collaborator

None the less, this is very cool!

0 Likes