Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
pdf文件中的相对文件链接_Pdf_Abcpdf_Html To Pdf - Fatal编程技术网

pdf文件中的相对文件链接

pdf文件中的相对文件链接,pdf,abcpdf,html-to-pdf,Pdf,Abcpdf,Html To Pdf,我正在创建一个pdf文件,我想链接到与pdf相同目录中的其他文件 即 我希望main.pdf有一些链接,可以使pdf上的默认程序打开其他pdf 由于我在服务器上生成这些文件,然后在下载到客户端时提供它们,因此我不能使用绝对链接,因为这些链接在客户端pc上不存在 所以首先,pdf文件是否真的支持像这样的相对文件链接,我还没有发现有多少证据表明它们可以这样做 另外,为了生成我的pdf,我使用abcpdf并提供html转换为pdf 为了尝试在html中生成正确的URL,我尝试了以下方法 <a h

我正在创建一个pdf文件,我想链接到与pdf相同目录中的其他文件

我希望main.pdf有一些链接,可以使pdf上的默认程序打开其他pdf

由于我在服务器上生成这些文件,然后在下载到客户端时提供它们,因此我不能使用绝对链接,因为这些链接在客户端pc上不存在

所以首先,pdf文件是否真的支持像这样的相对文件链接,我还没有发现有多少证据表明它们可以这样做

另外,为了生成我的pdf,我使用abcpdf并提供html转换为pdf

为了尝试在html中生成正确的URL,我尝试了以下方法

<a href='test.pdf'>test pdf link to local file</a>
<a href='#test.pdf'>test pdf link to local file</a>
<a href='/test.pdf'>test pdf link to local file</a>
<a href='file:///test.pdf'>test pdf link to local file</a>
<a href='file://test.pdf'>test pdf link to local file</a>

他们中的大多数人要么直接告诉我生成pdf文档的位置(临时文件路径),要么链接悬停显示“file:///test.pdf“在acrobat中,但单击它会弹出一个警告对话框,要求允许/拒绝,单击“允许”后,它将在firefox中打开url”file:///test.pdf"这不会解决任何问题


关于如何实现这一点,或者这种链接在PDF中是否可行,有什么想法吗?

我只能回答你的问题:PDF文件是否真的支持这样的相对文件链接

是的。我用main.pdf创建了一个小测试,它有两个指向同一文件夹中其他两个pdf文档的链接。我用Acrobat手动创建了链接,并将启动操作与链接注释相关联。请参见此处的内部结构:

这是带有主PDF和两个辅助PDF的zip。请注意,您可以将它们复制到任何位置,并且相关链接仍然有效。


我不确定你将如何使用abcpdf实现这一点,特别是因为你正在从HTML转换,这可能会限制可用的PDF功能。

因此,多亏@Frank Rem和abcpdf的帮助,我最终成功了

代码如下

    foreach (var page in Enumerable.Range(0, doc.PageCount))
    {
        doc.PageNumber = page;

        var annotEnd = doc.GetInfoInt(doc.Page, "Annot Count");

        for (var i = 0; i <= annotEnd; ++i)
        {
            var annotId = doc.GetInfoInt(doc.Page, "Annot " + (i + 1));

            if (annotId > 0)
            {
                var linkText = doc.GetInfo(annotId, "/A*/URI*:Text");

                if (!string.IsNullOrWhiteSpace(linkText))
                {
                    var annotationUri = new Uri(linkText);

                    if (annotationUri.IsFile)
                    {
                        // Note abcpdf temp path can be changed in registry so if this changes
                        // will need to rewrite this to look at the registry
                        // http://www.websupergoo.com/helppdfnet/source/3-concepts/d-registrykeys.htm
                        var abcPdfTempPath = Path.GetTempPath() + @"AbcPdf\";

                        var relativePath = annotationUri.LocalPath.ToLower().Replace(abcPdfTempPath.ToLower(), string.Empty);

                        // Only consider files that are not directly in the temp path to be valid files
                        // This is because abcpdf will render the document as html to the temp path
                        // with a temporary file called something like {GUID}.html
                        // so it would be difficult to tell which files are the document
                        // and which are actual file links when trying to do the processing afterwards
                        // if this becomes and issue this could be swapped out and do a regex on {GUID}.html
                        // then the only restriction would be that referenced documents cannot be {GUID}.html
                        if (relativePath.Contains("\\"))
                        {
                            doc.SetInfo(annotId, "/A*/S:Name", "Launch");
                            doc.SetInfo(annotId, "/A*/URI:Del", "");
                            doc.SetInfo(annotId, "/A*/F:Text", relativePath);
                            doc.SetInfo(annotId, "/A*/NewWindow:Bool", "true");
                        }
                    }
                }
            }
        }
    }
foreach(可枚举范围(0,doc.PageCount)中的变量页)
{
doc.PageNumber=第页;
var annoted=doc.GetInfoInt(doc.Page,“Annot Count”);
对于(变量i=0;i 0)
{
var linkText=doc.GetInfo(annotId,“/A*/URI*:Text”);
如果(!string.IsNullOrWhiteSpace(linkText))
{
var annotationUri=新Uri(linkText);
if(annotationUri.IsFile)
{
//注意abcpdf临时路径可以在注册表中更改,因此如果此更改
//需要重写此文件才能查看注册表
// http://www.websupergoo.com/helppdfnet/source/3-concepts/d-registrykeys.htm
var abcPdfTempPath=Path.GetTempPath()+@“AbcPdf\”;
var relativePath=annotationUri.LocalPath.ToLower().Replace(abcPdfTempPath.ToLower(),string.Empty);
//只考虑不是直接在临时路径中的文件为有效文件
//这是因为abcpdf将把文档作为html呈现给临时路径
//使用一个名为{GUID}.html的临时文件
//因此,很难判断哪些文件是文档
//以及之后尝试处理时的实际文件链接
//如果出现问题,则可以将其调出并在{GUID}.html上执行正则表达式
//那么唯一的限制就是引用的文档不能是{GUID}.html
if(relativePath.Contains(“\\”)
{
文件SetInfo(annotId,“/A*/S:Name”,“Launch”);
文档SetInfo(annotId,“/A*/URI:Del”,”;
文件SetInfo(注释,“/A*/F:Text”,相对路径);
文档SetInfo(annotId,“/A*/NewWindow:Bool”,“true”);
}
}
}
}
}
}

这将允许在pc上的查看器中打开与之相关的每个链接。

这看起来很有希望,我已经与abcpdf开发人员联系过,并且有一个api可以获得这种低级别设置,我只需要弄清楚如何使用它,我想你在那里显示的pdf信息会有很大帮助,将让你知道作为一个实验,你正在使用什么应用程序来查看结构,似乎找不到它它是一个内部工具(TallComponents)。链接是dead@Draex_我更新了链接。(文件仍然存在,但dropbox似乎已更改URL。)
    foreach (var page in Enumerable.Range(0, doc.PageCount))
    {
        doc.PageNumber = page;

        var annotEnd = doc.GetInfoInt(doc.Page, "Annot Count");

        for (var i = 0; i <= annotEnd; ++i)
        {
            var annotId = doc.GetInfoInt(doc.Page, "Annot " + (i + 1));

            if (annotId > 0)
            {
                var linkText = doc.GetInfo(annotId, "/A*/URI*:Text");

                if (!string.IsNullOrWhiteSpace(linkText))
                {
                    var annotationUri = new Uri(linkText);

                    if (annotationUri.IsFile)
                    {
                        // Note abcpdf temp path can be changed in registry so if this changes
                        // will need to rewrite this to look at the registry
                        // http://www.websupergoo.com/helppdfnet/source/3-concepts/d-registrykeys.htm
                        var abcPdfTempPath = Path.GetTempPath() + @"AbcPdf\";

                        var relativePath = annotationUri.LocalPath.ToLower().Replace(abcPdfTempPath.ToLower(), string.Empty);

                        // Only consider files that are not directly in the temp path to be valid files
                        // This is because abcpdf will render the document as html to the temp path
                        // with a temporary file called something like {GUID}.html
                        // so it would be difficult to tell which files are the document
                        // and which are actual file links when trying to do the processing afterwards
                        // if this becomes and issue this could be swapped out and do a regex on {GUID}.html
                        // then the only restriction would be that referenced documents cannot be {GUID}.html
                        if (relativePath.Contains("\\"))
                        {
                            doc.SetInfo(annotId, "/A*/S:Name", "Launch");
                            doc.SetInfo(annotId, "/A*/URI:Del", "");
                            doc.SetInfo(annotId, "/A*/F:Text", relativePath);
                            doc.SetInfo(annotId, "/A*/NewWindow:Bool", "true");
                        }
                    }
                }
            }
        }
    }