donoka
Goto Top

Interne Links in PDF nachträglich Automatisiert erstellen

Hallo liebes Forum,

ich habe ein PDF Dokument, in dem ich gerne nachträglich interne Links (referenz von einer seite zu anderer seite) automatisiert erstellen möchte.

Folgendes Beispiel, ein PDF Dokument mit ca. 600 Seiten. In diesem Dokument gibt es jeweils ein zugehöriges Zahlenpaar in der Form "#XXXX" (bsp. #1234) auf zwei unterschiedlichen Seiten. Ziel wäre es, auf einer Seite mit der Maus über dieses Zahlenpaar zu gehen und direkt auf die zugehörige Seite zu springen, wo dieses nochmal steht.

Ist es möglich via Skript, diese zusammengehörigen Zahlenpaare zu verlinken im PDF Dokument?

Es wird nicht aus Excel, Word etc. herausgedruckt. Leider ist das Erstellprogramm nicht fähig Links zu erzeugen. Das PDF ist durchsuchbar und ich dachte, es könnte nicht so schwer sein via Skript soetwas nachträglich über das Dokument laufen zu lassen?

Vielleicht hat jemand Erfahrung. Vielen Dank schon einmal face-smile

Sebastian

Content-Key: 379254

Url: https://administrator.de/contentid/379254

Printed on: April 26, 2024 at 06:04 o'clock

Mitglied: 136588
Solution 136588 Jul 05, 2018 updated at 08:03:22 (UTC)
Goto Top
Ist es möglich via Skript, diese zusammengehörigen Zahlenpaare zu verlinken im PDF Dokument?
Japp. Mit pdfsharp geht sowas z.B. https://sourceforge.net/projects/pdfsharp/
So ein Skript gibt's jetzt aber nicht für lau, sollte klar sein.
Member: donoka
donoka Jul 05, 2018 at 08:12:47 (UTC)
Goto Top
Danke erst mal, das hört sich spannend an, aber noch nicht wirklich durchsichtig für mich.
Wie lässt sich das ausführen, weil auf Windows kriege ich das gerade nicht hin.

Was genau meinst du damit, das Skript gibt es nicht für lau? Du würdest sowas programmieren, aber nicht für lau, oder es gibt so eine Lösung zu kaufen?
Mitglied: 136588
136588 Jul 05, 2018 updated at 08:15:49 (UTC)
Goto Top
Du würdest sowas programmieren, aber nicht für lau
Japp. Custom requirement meets custom code.

http://www.pdflinkeditor.com
Member: donoka
donoka Jul 05, 2018 at 12:29:44 (UTC)
Goto Top
Alles klar, wie könnten wir weiter vorgehen?
Mitglied: 136588
136588 Jul 05, 2018 updated at 12:43:57 (UTC)
Goto Top
Hast du zufällig Adobe Acrobat (nicht den Reader)? Damit müsste sich das auch machen lassen.
Member: donoka
donoka Jul 05, 2018 at 12:47:13 (UTC)
Goto Top
Yep, steht zur Verfügung face-smile
Mitglied: 136588
136588 Jul 05, 2018 updated at 12:50:51 (UTC)
Goto Top
Darfst du das PDF per Mail schicken oder auszugsweise geschwärzt zum Download stellen damit ich es daran testen kann?
=> PN
Member: colinardo
Solution colinardo Jul 05, 2018, updated at Jun 23, 2023 at 10:32:31 (UTC)
Goto Top
Servus Sebastian,
sowas ähnliches habe ich schon mal für jemanden mit Acrobat Pro in VBS gescriptet, hier mal für deinen Anwendungszweck angepasst. Voraussetzung ist ein installierter Adobe Acrobat. Den Code speicherst du als *.vbs und ziehst dann per Drag n' Drop deine PDF auf die Skriptdatei. Mit Acrobat ist das zwar bei 600 Seiten etwas lahm (der bietet nur sehr ineffektive Methoden zum Text-Extract per API an) aber funktioniert.
Der Code durchsucht dein PDF auf zwei zusammengehörige Wörter nach dem Regex-Schema #\d+, also eine Raute zwingend gefolgt von mindestens einer Zahl.
Diese Marker werden paarweise mit einer unsichtbaren Linkbox versehen die auf den jeweiligen Partner zeigt, er Link markiert dann beim Klick darauf den Zielterm auf der Zielseite.
' Check commandline arguments  
If WScript.Arguments.Count = 1 Then
	file = WScript.Arguments(0)
Else
	MsgBox "Parameteranzahl ist nicht korrekt, bitte nur einen Pfad zu einem PDF übergeben!",vbExclamation  
	WScript.Quit	
End If

' Show info messagebox  
if MsgBox("The following process starts when you click OK and will work in the background. When it's finished, Acrobat will show the modified document and a message will be shown. This process can take some time, so please be patient." & vbNewline & vbNewline & "Shall we start?",vbInformation Or vbSystemModal or vbYesNo,"Link converter script") = vbNo then wscript.quit  

' create objects  
Set objAcro = CreateObject("AcroExch.App")  
Set regex = CreateObject("VBScript.Regexp")  
Set oDic = CreateObject("Scripting.Dictionary")  
Set objShell = CreateObject("Wscript.Shell")  

' set regex object properties  
regex.IgnoreCase = True
regex.Pattern = "^\d+$"  

' action on file  
BatchProcessFile file
' cleanup  
Set fso = Nothing
Set objAcro = Nothing
Set regex = Nothing
Set oDic = Nothing
Set objShell = Nothing

Sub BatchProcessFile(f)
	' create acrobat objects  
	Set docAV = CreateObject("AcroExch.AVDoc")  
	Set docPD = CreateObject("AcroExch.PDDoc")  
	' open pdf  
	ret = docAV.Open(f,"")  

	' get document object  
	Set docPD = docAV.GetPDDoc()
	Set jsDoc = docPD.GetJSObject()
	' iterate over all pages in document  
	For p = 0 To jsDoc.numPages - 1
		' itterate over every word in page  
		For w = 0 To jsDoc.getPageNumWords(p) - 1
			' if word is a '#'  
			If jsDoc.getPageNthWord(p,w,False) = "#" Then  
				' get next word ...  
				markerName = jsDoc.getPageNthWord(p,w + 1,True)
				' ... and check against the regex  
				If regex.Test(markerName) Then
					' get position coordinates of marker  
					pos1 = jsDoc.getPageNthWordQuads(p,w)
					pos2 = jsDoc.getPageNthWordQuads(p,w + 1)
					tlX = pos1(0)(0)
					tlY = pos1(0)(1)
					brX = pos2(0)(6)
					brY = pos2(0)(7)
					' add dictionary entries with marker name as key and value as [PageNum]#[tlX];[tlY];[brX];[brY] joined by '|'  
					If Not oDic.Exists(markerName) Then
						oDic.Add markerName,p & ":" & w+1 & "#" & Join(Array(tlX,tlY,brX,brY),";")  
					Else
						If InStr(1,oDic.Item(markerName),"|",1) = 0 Then  
							oDic.Item(markerName) = oDic.Item(markerName) & "|" & p & ":" & w+1 & "#" & Join(Array(tlX,tlY,brX,brY),";")  
						End If
					End If
				End If
			End If
		Next
	Next
	' iterate over all keys in dictionary  
	For Each k In oDic.Keys
		' split matching markers  
		dItems = Split(oDic.Item(k),"|",2,1)  
		If UBound(dItems) = 1 Then
			' split data of markers  
			dItem1 = Split(dItems(0),"#",2,1)  
			dItem2 = Split(dItems(1),"#",2,1)  
			' get coordinates  
			c1 = Split(dItem1(1),";",4,1)  
			c2 = Split(dItem2(1),";",4,1)  
			' extract page and word position index 0 = page index 1 = word position  
			pwItem1 = Split(dItem1(0),":",2,1)  
			pwItem2 = Split(dItem2(0),":",2,1)  
			
			'create link objects  
			Set l1 = jsDoc.addLink(CInt(pwItem1(0)),Array(CDbl(c1(0)),CDbl(c1(1)),CDbl(c1(2)),CDbl(c1(3))))
			Set l2 = jsDoc.addLink(CInt(pwItem2(0)),Array(CDbl(c2(0)),CDbl(c2(1)),CDbl(c2(2)),CDbl(c2(3))))
			' set link action  
			l1.setAction("this.selectPageNthWord(" & pwItem2(0) & "," & pwItem2(1) & ",true)")  
			l2.setAction("this.selectPageNthWord(" & pwItem1(0) & "," & pwItem1(1) & ",true)")  
		End If
		
	Next
	' Show Acrobat window  
	objAcro.Show
	msgbox "Process finished.",vbInformation Or vbSystemModal,"Link converter script"  
	'jsDoc.saveAs(f)  
	'jsDoc.closeDoc()  
	'objAcro.Hide()  
	'objAcro.Exit()  
	
	Set jsDoc = Nothing
	Set docAV = Nothing
	Set docPD = Nothing
End Sub
Viel Spaß
Grüße Uwe
Member: donoka
donoka Jul 06, 2018 at 09:25:32 (UTC)
Goto Top
Wow, vielen Dank Uwe!
Funktioniert für standard dateien aus Word richtig gut. Wenn ich aus einem anderen Programm raus drucke (2D Zeichenprog) habe ich noch meine Probleme, aber da werde ich jetzt mit dem debuggen anfangen.
Viele Grüße,
Sebastian