我有很多旧报告的扫描页面存储在以下目录结构中:
Report 1/
contents.pdf
execsummary.pdf
chapter 1/
page 1.pdf
page 2.pdf
page 3.pdf
chapter 2/
page 4.pdf
page 5.pdf
page 6.pdf
我想Report 1.pdf
从这些书签中生成与目录结构匹配的书签。我该怎么做?
我在 Windows 10 上,没有 Adobe Acrobat,但我有 Foxit Phantompdf。
答案1
这可能不是您正在寻找的解决方案:
您可以使用 LaTeX 来实现这一点。您需要以另一种方式生成 TeX 文件,例如您最喜欢的编程语言。这需要您知道如何编程、使用 LaTeX,当然还要安装所需的工具。
如果您有兴趣,我可以详细说明这一点并添加示例脚本。
编辑:
我编写了一个小型 FreeBASIC 程序(有点脏,但能完成工作)来生成 .tex 文件。然后可以使用例如 Miktex 和 TexnicCenter 来生成最终的 pdf 文件。
- 从以下网址下载并解压 FreeBASIC 编译器http://www.freebasic.net/(我用了
FreeBASIC-1.05.0-win64.zip
)。 - 将下面的代码保存为
code.bas
,然后用进行编译fbc.exe code.bas
。 - 将“Report 1”、“Report 2”等文件夹拖放到新的可执行文件中
code.exe
。这将在各自的文件夹中生成文件“Report 1.tex”、“Report 2.tex”。 - 从以下位置下载并安装 Miktexhttp://www.miktex.org/(在安装过程中启用软件包的即时安装)和 TexnicCenter 来自http://www.texniccenter.org/download/并在 TexnicCenter 中打开报告文件。我不确定您是否需要对默认设置进行任何更改,但互联网上有很多这方面的资源。编译时
LaTeX -> PDF
应该安装缺少的软件包。
源代码:明确处理提到的文件夹结构和文件名,仅此而已。
' Drag and drop folders onto the executable in order to generate a .tex-file
' which can be used to merge the pdfs in each passed folder using LaTeX.
'
#include "vbcompat.bi"
sub expandEnviron__isFileOrFolder ( byref strPath as string )
dim iLetter as integer
if left(strPath,1)="%" then
for iLetter=2 to len(strPath)
if mid(strPath,iLetter,1)="%" then
strPath=environ(mid(strPath,2,iLetter-2))+right(strPath,len(strPath)-iLetter)
exit for
end if
next iLetter
end if
end sub
function isFileOrFolder ( byref strPath as string, byval expPath as string ptr = 0 ) as integer
' return value:
' 0: path doesn't exist
' 1: file
' 2: folder
'
dim strDir as string = curdir
dim as string strPathCopy
dim as string ptr pPath
if expPath then
*expPath = strPath
expandEnviron__isFileOrFolder(*expPath)
pPath = expPath
else
strPathCopy = strPath
expandEnviron__isFileOrFolder(strPathCopy)
pPath = @strPathCopy
end if
if fileExists(*pPath) then
return 1
elseif ( chdir(*pPath) = 0 ) then
chdir(strDir)
return 2
else
return 0
end if
end function
color(1,15)
cls
if command(1) = "" then
print "Drag and drop folders onto the executable."
sleep
end
end if
dim as string basedir
dim as string strPath = ""
dim as integer i = 1
' Process all command line arguments i.e process all folders.
while command(i) <> ""
basedir = command(i)
dim as string basedirName
' Make sure the argument is indeed a folder.
if isFileOrFolder(basedir,@strPath) = 2 then
if right(strPath,1) = "\" then basedir = left(strPath,len(strPath)-1)
basedirName = right(basedir,len(basedir)-instrrev(basedir,"\"))
print ""
print baseDirName
'
' Print some LaTeX commands.
open basedir+"\"+baseDirName+".tex" for output as #1
print #1, $"\documentclass{scrreprt}"
print #1, $"\usepackage{grffile}"
print #1, $"\usepackage{pdfpages}"
print #1, $"\usepackage{bookmark}"
print #1, $"\hypersetup{pageanchor=false}"
print #1, $"\begin{document}"
print #1, $"\pagestyle{empty}"
print #1, $"\pagenumbering{gobble}"
print #1, "%"
'
' Process contents.pdf.
dim as string tmp = basedir+"\contents.pdf"
if isFileOrFolder(tmp) = 1 then
print #1, $"\includepdf[pages=-]{contents.pdf}"
else
color(12,15):print chr(9);"missing contents.pdf":color(1,15)
end if
'
' Process execsummary.pdf.
tmp = basedir+$"\execsummary.pdf"
if isFileOrFolder(tmp) = 1 then
print #1, $"\includepdf[pages=-]{execsummary.pdf}"
else
color(12,15):print chr(9);"missing execsummary.pdf":color(1,15)
end if
'
' Process all subfolders named "chapter 1", "chapter 2" etc.
' If "chapter 4" exists but "chapter 3" does not, then "chapter 4" and
' all after that will be ignored.
dim as integer chapter_link_cnt = 0
dim as integer j = 1
dim as string nextChapterDir = basedir+$"\chapter "+str(j)
while isFileOrFolder(nextChapterDir) = 2
print #1, "%"
dim as integer k = 1
'
' Process all files named "page 1", "page 2" etc.
dim as string nextPage = nextChapterDir + $"\page "+str(k)+".pdf"
while isFileOrFolder(nextPage) = 1
if k = 1 then
chapter_link_cnt += 1
print #1, $"\includepdf[link,linkname=l";str(chapter_link_cnt); _
",pages=-]{chapter ";str(j);"/page ";str(k);".pdf}"
print #1, $"\bookmark[dest=l";str(chapter_link_cnt); _
".1]{chapter ";str(j);"}"
else
print #1, $"\includepdf[pages=-]{chapter ";str(j);"/page ";str(k);".pdf}"
end if
k += 1
nextPage = nextChapterDir + $"\page "+str(k)+".pdf"
wend
j += 1
nextChapterDir = basedir+$"\chapter "+str(j)
wend
'
print #1, $"\end{document}"
close #1
else
print ""
color(12,15):print "Error (not a folder): ";command(i):color(1,15)
end if
i += 1
wend
print ""
print ""
print "Done."
sleep
如果您想使用不同的语言(也许可以使用 powershell 脚本来完成),这里有一个示例 tex 文件:
\documentclass{scrreprt}
\usepackage{grffile}
\usepackage{pdfpages}
\usepackage{bookmark}
\hypersetup{pageanchor=false}
\begin{document}
\pagestyle{empty}
\pagenumbering{gobble}
%
\includepdf[pages=-]{contents.pdf}
\includepdf[pages=-]{execsummary.pdf}
%
\includepdf[link,linkname=l1,pages=-]{chapter 1/page 1.pdf}
\bookmark[dest=l1.1]{chapter 1}
\includepdf[pages=-]{chapter 1/page 2.pdf}
%
\includepdf[link,linkname=l2,pages=-]{chapter 2/page 1.pdf}
\bookmark[dest=l2.1]{chapter 2}
\includepdf[pages=-]{chapter 2/page 2.pdf}
%
\includepdf[link,linkname=l3,pages=-]{chapter 3/page 1.pdf}
\bookmark[dest=l3.1]{chapter 3}
\includepdf[pages=-]{chapter 3/page 2.pdf}
\includepdf[pages=-]{chapter 3/page 3.pdf}
\includepdf[pages=-]{chapter 3/page 4.pdf}
\end{document}
答案2
答案3
我遇到了同样的问题,最后只能使用 Excel VBA 编写自己的代码。我已将模块上传到 Github: https://github.com/markbrauning/BlueBeam-eX-Excel-Submittal-from-Folder-Structure
请注意,此模块要求您安装 Bluebeam eXtreme,因为它使用 ScriptEngine 命令行进行实际的 PDF 合并。
Dim i As Long, k As Long
Dim scriptRevu As String
Dim SectionPDFpath As String
Dim PDFFilePath As String
Dim SectionFolder As String
Dim QuoteCheck As Boolean
For i = 0 To UBound(xFoldersList_temp, 2)
SectionFolder = xFoldersList_temp(0, i)
'---SectionPDFpath = ParentFolderPath + SubFolderName + .pdf
SectionPDFpath = xFoldersList_temp(3, i) & "\" & xFoldersList_temp(1, i) & ".pdf"
scriptRevu = "Open('" & SectionPDFpath & "', '')"
QuoteCheck = Not GetFilesList(SectionFolder, False, "pdf", 0)
If QuoteCheck Then GoTo Sub_Exit
For k = 0 To UBound(xFilesList, 1)
PDFFilePath = xFilesList(k)
scriptRevu = scriptRevu & " " & "InsertPages(9999, '" & PDFFilePath & "', true, false, false, false, false)"
Next k
scriptRevu = scriptRevu & " Save('" & SectionPDFpath & "', 1)"
scriptRevu = scriptRevu & " Close(true, 1)"
RunRevuScript scriptRevu
'if next script is for the next folder depth up, then wait for a few seconds
If Not (i = UBound(xFoldersList_temp, 2)) Then
If xFoldersList_temp(2, i) <> xFoldersList_temp(2, i + 1) Then
waitdepth Int(xFoldersList_temp(2, i + 1)), 7
End If
End If
Next i
RunRevuScript 是一个通过 shell 发送书面命令的函数
Sub RunRevuScript(RevuScript As String)
Dim RevuPath As String
Dim command As String
RevuPath = "C:\Program Files\Bluebeam Software\Bluebeam Revu\20\Revu\ScriptEngine.exe"
command = RevuPath & " " & RevuScript
Shell command, vbNormalFocus
End sub
希望这对某人有帮助!