Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert multi page PDF

15 REPLIES 15
Reply
Message 1 of 16
Anonymous
2949 Views, 15 Replies

Insert multi page PDF

I am trying to create a function to automatically insert multi-page pdf documents into AutoCAD.

Should be simple, but I can't get AutoCAD to recognize that it has reached the last page of the pdf document or set a variable to the total number of pages in the pdf document.  It works as is but you have to escape out of it's failure to insert the non-existant page after the last page.  Would like an elegent automatic way out before distributing this to other users.

Here's what I've got:

 

(defun c:PDF ()
  (setq fname (getfiled "Select PDF to Insert" (getvar 'dwgprefix) "pdf" 0))
  (setq ipoint (getpoint "select insertion point"))
  (setq pagenum 1)
  (setq pagetotal 15) ; is there a system variable that can give me the actual number?
  (while (< pagenum pagetotal)
    (setq catchit (vl-catch-all-apply '(lambda () (command "-pdfattach" fname pagenum ipoint 1 0 ))))
    (if (vl-catch-all-error-p catchit) (setq pagenum pagetotal) (setq pagenum (+ pagenum 1))) ; apparently no more pages is not an error
    (setq ipoint (list (car ipoint) (- (cadr ipoint) 8.5)))
  ) ;while
) ;PDF

15 REPLIES 15
Message 2 of 16
lando7189
in reply to: Anonymous

To get the number of pages in a PDF file, get the total number of regular expression matches of "/Type\s*/Page[^s]" within the file contents.  - Lanny

Message 3 of 16
lando7189
in reply to: lando7189

Actually... you can find the count in the PDF file:

 

(defun GetPdfPageCount (FileName / File TextItem TypePages Count)
  (if (setq File (open FileName "r"))
    (progn
      (while (and (not Count) (setq TextItem (read-line File)))
	(if (wcmatch TextItem "/Type /Pages*")
          (setq TypePages T)
          (if (wcmatch TextItem "/Count [0-9]*")
            (setq Count (atoi (substr TextItem 7)))
          )
        )
      )
      (setq File (close File))
    )
  )
  Count
)
Message 4 of 16
danglar
in reply to: Anonymous

probably something like this:

 

(defun c:DF () Multipage PDF Insert
  (setq fname (getfiled "Select PDF to Insert" (getvar 'dwgprefix) "pdf" 0))
  (setq ipoint (getpoint "select insertion point"))
  (setq pagenum 1)
  (setq pagetotal (getreal "\nType Total Number of Pages you want to Insert: "))
  (while (<= pagenum pagetotal)
    (setq catchit (vl-catch-all-apply '(lambda () (command "-pdfattach" fname pagenum ipoint 1 0 ))))
    (if (vl-catch-all-error-p catchit) (setq pagenum pagetotal) (setq pagenum (+ pagenum 1))) ; apparently no more pages is not an error
    (setq ipoint (list (car ipoint) (- (cadr ipoint) 8.5)))
  ) ;while
) ;PDF
(c:df)

Message 5 of 16
danglar
in reply to: danglar

I tried to do this function for group of PDF, but it works only for first two ones. Probably somebody knows how to fix it?


(defun c:pdf (/ lst a b fin)
 
  ;; DosLib required

 


  (if (setq lst (dos_getfilem "Select PDF's to insert:" (getvar "dwgprefix") "" ))
    ((lambda (layers)
       (foreach file (vl-sort (cdr lst) (function >))
(setq ipoint (getpoint "select insertion point"))
(setq pagenum 1)
  (setq pagetotal (getreal "\nType Total Number of Pages you want to Insert: "))
         (if fin
           (progn
             (vla-GetBoundingBox (car fin) 'a 'b)
             (setq b (vlax-safearray->list b))
             (vl-cmdf "_pdfattach" (strcat (car lst) file) (list 0. (1+ (cadr b))) "")
   )       

(while (<= pagenum pagetotal)
    (setq catchit (vl-catch-all-apply '(lambda () (command "-pdfattach" (strcat (car lst) file) pagenum ipoint 1 0 ))))
    (if (vl-catch-all-error-p catchit) (setq pagenum pagetotal) (setq pagenum (+ pagenum 1))) ; apparently no more pages is not an error
    (setq ipoint (list (car ipoint) (- (cadr ipoint) 8.5)))
  ) ;while


 ;          (vl-cmdf "_pdfattach" (strcat (car lst) file) ipoint "")

 


         )
         (vla-put-layer
           (car (setq fin (cons (vlax-ename->vla-object (entlast)) fin)))
           (vla-get-name (vla-add layers (vl-filename-base file)))
         )
       )
     )
      (vla-get-layers
        (cond (*AcadDoc*)
              ((setq *AcadDoc* (vla-get-activedocument (vlax-get-acad-object))))
        )
      )
    )
  )
  (princ)
)
(c:pdf)

Message 6 of 16
Anonymous
in reply to: lando7189

Looked promising but my 4 page PDF file has no instances of "/Count" and only one instance of "/Pages".  I thought maybe this:

/PageLayout/SinglePage/PageMode/UseThumbs/Pages 3 0

But it is a 4 page document, not a 3 page document.

Any other ideas how PDF pages could be counted?

Message 7 of 16
dbroad
in reply to: Anonymous

Mark,

The situation is more complex than the programs posted accomodate.  Programs need to look for /N sequences  /count sequences among others.  Are you trying to sell the resulting program? Reducing the need for someone hit the escape key to stop the program is hardly worth all this effort for a free solution.

 

Doug

Architect, Registered NC, VA, SC, & GA.
Message 8 of 16
Anonymous
in reply to: Anonymous

Was hoping to include it as a free extra utility in a package being sold that interacts with a database app. I'm happy to use it as is but wouldn't want to distribute it this way, even as a freebie.
Message 9 of 16
Anonymous
in reply to: Anonymous

Thought it might be easy since pdfattach is already evaluating this kind of info.
Message 10 of 16
hmsilva
in reply to: Anonymous


@Anonymous wrote:

I am trying to create a function to automatically insert multi-page pdf documents into AutoCAD.

Should be simple, but I can't get AutoCAD to recognize that it has reached the last page of the pdf document or set a variable to the total number of pages in the pdf document.  It works as is but you have to escape out of it's failure to insert the non-existant page after the last page.  Would like an elegent automatic way out before distributing this to other users.

...


Hi Mark,

 

for an elegent automatic way, you'll have to be a member, but this Lee Mac's '_PDFPageCount' using 'Scripting.FileSystemObject' and 'VBScript.RegExp' calculates the correct number of pages.

 

Not so 'elegent automatic way', perhaps something like this will do the trick

 

(defun c:PDF (/ fname ipoint pagenum)
  (if (and (setq fname (getfiled "Select PDF to Insert" (getvar 'dwgprefix) "pdf" 0))
           (setq ipoint (getpoint "select insertion point"))
           (setq pagenum 0)
      )
    (while (progn (vl-cmdf "-pdfattach" fname (setq pagenum (1+ pagenum)))
                  (if (wcmatch (getvar 'LASTPROMPT) (strcat "*" fname "*"))
                    (command)
                    (vl-cmdf ipoint 1 0)
                  )
           )
      (setq ipoint (list (car ipoint) (- (cadr ipoint) 8.5)))
    ); while
  ); if
  (princ)
); PDF

 

Hope this helps,
Henrique

EESignature

Message 11 of 16
aliff_ahtenk
in reply to: Anonymous

Hai.. i am using the previous provided reply, and with some alteration, here are the code. but i do not know whether it can be use with autocad or not, because i am using other application.

 

(defun c:MP (/ fname ipoint pagenum)
   (setq fname (getfiled "Select PDF to Insert" (getvar 'dwgprefix) "pdf" 0))
   (setq ipoint '(0 0))
   (setq pagenum 1)
   (setq pagelast (getreal "\nType Total Number of Pages you want to Insert: "))

   (while (<= pagenum pagelast)
          (command "_pdfimport" "f" fname pagenum ipoint "" "")
          (prompt "\nLook like we have another page.")
          (setq ipoint (list (car ipoint) (+ (cadr ipoint) 150)))
          (setq pagenum (+ 1 pagenum))
          (if (> pagenum pagelast)
              (and (prompt "\nAll pages have been imported.")
                   (exit)
                   );and;
              );if;
          );while;
   (princ)
);MP;

 

For on my use, it can function, but the object inserted is blocked on the same block. I wonder if it can be inserted on different block and name. Just naming according to page name is enough.

 

there is another discussion on this but i am not yet go thru it. here are the link:
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/insert-pdf-pages-help/td-p/9890051 

Message 12 of 16
scot-65
in reply to: Anonymous

3/21/2024 Revisited - Need to insert each page manually into a checkerboard style model space.

 

AutoCAD R2024-LT

 

Lando's method is not through enough.

Opening 3 random PDF's here showed two of them had "Count" and the third had meta data to a file outside the realm of the pdf file itself:

 

<</ITXT(4.1.6)/Kids[1 0 R 676 0 R 961 0 R]/Count 3/Type/Pages>>

] /Count 10

<</Length 3348/Subtype/XML/Type/Metadata>>stream

 

 

Lee Mac's shows promise but the following 2 lines are not available for R2024-LT

(vlax-create-object "Scripting.FileSystemObject")
(vlax-create-object "VBScript.RegExp")

 

 

Hmsilva works, but I need to manually place each PDF page on a checkerboard style model space.

The first checkerboard row may require 2 or 3 boxes to be fill out.

The second row 2, 3, 4, or 5 boxes to fill out, etc.

The following is what I have come up with to bring in the PDF pages and manually place them.

 

(defun c:I-PDF ( / fn n )
 (princ "Insert PDF (PDFATTACH) ")
 (if (and (setq fn (getfiled "Select PDF file to Insert" (getvar "DWGPREFIX") "pdf" 0) n 0)
          (findfile fn))
  (while fn
   (setvar "CMDECHO" 0)
   (command "-PDFATTACH" fn (setq n (1+ n)))
   (if (wcmatch (getvar "LASTPROMPT") (strcat "*" fn "*"))
    (progn
     (setvar "CMDECHO" 1)
     (setq fn (command))
    );progn
    (progn
     (command (getvar "VIEWCTR") 1 0.0)
     (setvar "CMDECHO" 1)(princ "\n")
     (command "MOVE" "Last" "" (getvar "VIEWCTR") pause)
    );progn
   );if
  );while
  (princ "\n PDF file not found. ")
 );if
 (setq fn nil n nil)(princ)
);end I-PDF

 

Thanks goes out to Hmsilva for providing the code.

 

From here I plan to create a dialog box which gives the option to insert all pages or provide an edit box to enter specific pages - in a preferred order (I desire this method as well). Insert odd pages first, then even pages is also on the plate.

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 13 of 16
Sea-Haven
in reply to: Anonymous

I answered with a possible solution some time ago that opened a PDF and made images of every page, then inserted all those images in a dwg so you could pick a page to insert, rather than guess the page number, the solution was the use of Ghostcript to create the images. It imported the images in a checker pattern based on number of pages 1 column 2 3 etc.

 

I remember now had problems running the ghostcript command from lisp worked properly when ran as a Bat file from windows, the poster decided to give up so I did to. Will try to find. 

 

I am pretty sure Lee-Mac has posted some stuff about reading pdf properties.

Message 14 of 16
htran4
in reply to: scot-65

Thanks for your lisp, @scot-65
Is there any quick command or lisp to be used to replace the inserted PDFs with a new PDFs but different filename?
Thanks.

Message 15 of 16
baksconstructor
in reply to: htran4


@htran4 wrote:

Is there any quick command or lisp to be used to replace the inserted PDFs with a new PDFs but different filename?


Search the Internet by name - AutoImportCAD

Message 16 of 16
vladimir_michl
in reply to: Sea-Haven

You don't need to "guess" the number of pages inside the PDF, you can use AutoCAD command to detect the count. See the MPDFIMPORT LISP utility - https://www.cadforum.cz/en/bulk-import-pages-from-a-multi-page-pdf-into-autocad-tip13622

 

Vladimir Michl, www.arkance.world  -  www.cadforum.cz

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report