C# 让Javascript在ABC pdf中呈现pdf之前完成

C# 让Javascript在ABC pdf中呈现pdf之前完成,c#,javascript,google-maps,abcpdf,C#,Javascript,Google Maps,Abcpdf,我正在尝试制作一个网页的pdf,该网页显示谷歌地图上的位置。唯一的问题是,在ABCpdf呈现pdf时,Javascript还没有完全完成。这是不完整的。如何让pdf等到javascript 100%完成后再呈现pdf。这是我到目前为止所做的尝试 Doc theDoc = new Doc(); string theURL = url; // Set HTML options theDoc.HtmlOptions.AddLink

我正在尝试制作一个网页的pdf,该网页显示谷歌地图上的位置。唯一的问题是,在ABCpdf呈现pdf时,Javascript还没有完全完成。这是不完整的。如何让pdf等到javascript 100%完成后再呈现pdf。这是我到目前为止所做的尝试

Doc theDoc = new Doc();
            string theURL = url;
            // Set HTML options
            theDoc.HtmlOptions.AddLinks = true;
            theDoc.HtmlOptions.UseScript = true;
            theDoc.HtmlOptions.PageCacheEnabled = false;
            //theDoc.HtmlOptions.Engine = EngineType.Gecko;
            // JavaScript is used to extract all links from the page

            theDoc.HtmlOptions.OnLoadScript = "var hrefCollection = document.all.tags(\"a\");" +
              "var allLinks = \"\";" +
              "for(i = 0; i < hrefCollection.length; ++i) {" +
              "if (i > 0)" +
              "  allLinks += \",\";" +
              "allLinks += hrefCollection.item(i).href;" +
              "};" +
              "document.documentElement.abcpdf = allLinks;";
            // Array of links - start with base URL
            theDoc.HtmlOptions.OnLoadScript = "(function(){window.ABCpdf_go = false; setTimeout(function(){window.ABCpdf_go = true;}, 1000);})();";
            ArrayList links = new ArrayList();
            links.Add(theURL);
            for (int i = 0; i < links.Count; i++)
            {
                // Stop if we render more than 20 pages
                if (theDoc.PageCount > 20)
                    break;
                // Add page
                theDoc.Page = theDoc.AddPage();
                int theID = theDoc.AddImageUrl(links[i] as string);
                // Links from the rendered page
                string allLinks = theDoc.HtmlOptions.GetScriptReturn(theID);
                string[] newLinks = allLinks.Split(new char[] { ',' });
                foreach (string link in newLinks)
                {
                    // Check to see if we allready rendered this page
                    if (links.BinarySearch(link) < 0)
                    {
                        // Skip links inside the page
                        int pos = link.IndexOf("#");
                        if (!(pos > 0 && links.BinarySearch(link.Substring(0, pos)) >= 0))
                        {
                            if (link.StartsWith(theURL))
                            {
                                links.Add(link);
                            }
                        }
                    }
                }
                // Add other pages
                while (true)
                {
                    theDoc.FrameRect();
                    if (!theDoc.Chainable(theID))
                        break;
                    theDoc.Page = theDoc.AddPage();
                    theID = theDoc.AddImageToChain(theID);
                }
            }
            // Link pages together
            theDoc.HtmlOptions.LinkPages();
            // Flatten all pages
            for (int i = 1; i <= theDoc.PageCount; i++)
            {
                theDoc.PageNumber = i;
                theDoc.Flatten();
            }

            byte[] theData = theDoc.GetData();

            Response.Buffer = false; //new
            Response.Clear();
            //Response.ContentEncoding = Encoding.Default;
            Response.ClearContent(); //new
            Response.ClearHeaders(); //new
            Response.ContentType = "application/pdf"; //new
            Response.AddHeader("Content-Disposition", "attachment; filename=farts");

            Response.AddHeader("content-length", theData.Length.ToString());
            //Response.ContentType = "application/pdf";
            Response.BinaryWrite(theData);
            Response.End();

            theDoc.Clear();
Doc theDoc=new Doc();
字符串theURL=url;
//设置HTML选项
theDoc.HtmlOptions.AddLinks=true;
theDoc.HtmlOptions.UseScript=true;
theDoc.HtmlOptions.PageCacheEnabled=false;
//theDoc.HtmlOptions.Engine=EngineType.Gecko;
//JavaScript用于从页面中提取所有链接
theDoc.HtmlOptions.OnLoadScript=“var hrefCollection=document.all.tags(\'a\”)+
“var allLinks=\”\“;”+
“对于(i=0;i0)”+
“所有链接+=\”,\”;”+
“allLinks+=hrefCollection.item(i).href;”+
"};" +
“document.documentElement.abcpdf=allLinks;”;
//链接数组-从基本URL开始
theDoc.HtmlOptions.OnLoadScript=“(函数(){window.ABCpdf_go=false;设置超时(函数(){window.ABCpdf_go=true;},1000);}();”;
ArrayList links=新的ArrayList();
links.Add(网址);
for(int i=0;i20)
打破
//添加页面
theDoc.Page=theDoc.AddPage();
int theID=doc.AddImageUrl(链接[i]为字符串);
//来自呈现页面的链接
字符串allLinks=theDoc.HtmlOptions.GetScriptReturn(theID);
字符串[]newLinks=allLinks.Split(新字符[]{',});
foreach(newLinks中的字符串链接)
{
//检查是否已准备好呈现此页面
if(links.BinarySearch(link)<0)
{
//跳过页面内的链接
int pos=link.IndexOf(“#”);
if(!(pos>0&&links.BinarySearch(link.Substring(0,pos))>=0))
{
if(link.StartsWith(theURL))
{
链接。添加(链接);
}
}
}
}
//添加其他页面
while(true)
{
theDoc.FrameRect();
如果(!theDoc.Chaineable(theID))
打破
theDoc.Page=theDoc.AddPage();
theID=DOC.AddImageToChain(theID);
}
}
//将页面链接在一起
theDoc.HtmlOptions.LinkPages();
//展平所有页面

对于(int i=1;i尝试将脚本块变成javascript函数,并从文件顶部的
document.ready()
函数调用该函数。我假设您使用的是jQuery
函数将确保在调用其正文中的任何函数之前,所有页面元素都已稳定。

我遇到了一个非常类似的问题(将Google Visualization呈现为PDF),下面是我用来部分解决该问题的技巧:

首先,您的JavaScript需要在
DOMContentLoaded
上执行,而不是在
load
上执行(您马上就会明白为什么)。接下来创建一个空页面,通过计时器提供内容(您可以使用
System.Threading.Thread.Sleep
使页面“等待”一定时间)

然后在要呈现为PDF的页面上放置一个隐藏图像,该图像包含在生成PDF之前需要执行的JavaScript。图像的“src”属性必须有一个指向计时器页面的URL(在下面的示例中,我通过查询字符串指定以毫秒为单位的延迟):


请注意,我使用了
visibility:hidden
而不是
display:none
来隐藏图像。原因是某些浏览器可能在图像可见之前不会开始加载图像

现在将发生的是,ABCpdf将等待图像加载,而JavaScript将已经执行(因为
DOMContentLoaded
load
之前启动,它将等待所有图像加载)

当然,您无法预测执行JavaScript需要多少时间。另一件事是,如果ABCpdf无法在15秒内加载页面(默认值,但我认为您可以更改),它将引发异常,因此在选择延迟时要小心


希望这能有所帮助。

在我的例子中,我们正在将v8升级到v9,并生成一个网页的缩略图,该网页还需要大量的javascript CSS操作来定位对象。当我们切换到v9时,我们注意到对象被复制了(显示在其原始位置和js后应位于的位置)

我应用的解决方法是使用RenderDelay和OneStageRender属性来更改如何将页面呈现处理为PDF。500毫秒,因此是1/2秒。更大的罪魁祸首似乎是OneStageRender。为了正确处理呈现,必须禁用它

doc.SetInfo(0, "RenderDelay", "500")
doc.SetInfo(0, "OneStageRender", 0)

请更具体地说明您希望在其他部分完成之前等待执行代码的哪一部分。哇,这一定是我见过的最清晰的解决方法!或者您可以在文档中查找
RenderDelay
ABCpdf_RenderWait
ABCpdf_go
,以获得一种不太男性化的方法;@k
doc.SetInfo(0, "RenderDelay", "500")
doc.SetInfo(0, "OneStageRender", 0)