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
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
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 )
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)
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)
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?
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
@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
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
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.
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.
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.