【问题标题】:Save the document generated by javascript保存javascript生成的文档
【发布时间】:2009-09-25 18:59:17
【问题描述】:

Javascript 可以操作浏览器正在显示的文档,所以如下:

<script>
    document.write("<table><tr><td>Hola</td><td>Adios</td></tr></table>");
</script>

将使浏览器显示一个表格,就像它是原始 HTML 文档一样:

<table>
    <tr>
        <td>Hola</td>
        <td>Adios</td>
    </tr>
</table>

有没有办法可以保存/提供此文档内容?

目前我们有一些使用 Ext-js 生成的漂亮报告,我想做的是拥有它的“text/html”版本(我的意思是,不需要 javascript 的东西)

所以在页面末尾我会添加一个按钮:“另存为 blaba”,文档应该显示文本/纯文本版本。

我现在能想到的唯一方法是将内容写入 javascript 变量,例如:

 var content = document.toString(); // or something magic like that.
 // post it to the server

然后将该值发布到服务器,并让服务器显示该值。

 <%=request.getParameter("content-text")%>

但是看起来很棘手。

还有其他选择吗?

编辑

好的,我几乎明白了。现在我只需要弹出新窗口,以便显示“您要保存它吗”选项

这就是我目前所得到的

<script>
    document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
    function saveAs(){
        var sMarkup =  document.getElementById('content').innerHTML; 
        var oNewDoc = document.open('application/vnd.ms-excel');        
        oNewDoc.write( sMarkup + "<hr>" );
        oNewDoc.close();
    }
</script>

<input type="button" value="Save as" onClick="saveAs()"/>

行:

    var oNewDoc = document.open('application/vnd.ms-excel');        

应该指定新的内容类型,但它被忽略了。

【问题讨论】:

    标签: javascript document client-side server-side html-generation


    【解决方案1】:

    除非在客户端使用File -&gt; Save Page As... 保存它,否则您必须完全按照您的建议进行操作,将$('body').html() 发布到您的服务器并将其作为文本处理。

    【讨论】:

    • File-Save page as: would save "document.write('html... etc etc ) 不是吗?我想要像“File-Save as”这样的东西,保存的就是"
    • @Oscar Reyes:您可以制作一个按钮,打开一个新窗口,其中只有带有 javascript 的表格,然后保存。
    • 我被困在“...打开一个新窗口”部分:-/
    • @Oscar Reyes:尽管如此,你还是必须在服务器端进行。您必须获取完整的客户端表,将其发布到服务器并在新窗口中打开新的“页面”。稍后我会尝试更详细的说明。
    • @OscarRyz:先生,请看stackoverflow.com/questions/10679927/…
    【解决方案2】:

    这里是升级版,可以打开.xls格式的表格内容。

    <head>
    <script>
    
             document.write("<table id='targetTable'><tr><td>Hola</td><td>Adios</td></tr><tr><td>eins</td><td>zwei</td></table>"); 
            function saveAsXLS()
            {
                var xlObj = new ActiveXObject("Excel.Application");
                var xlBook = xlObj.Workbooks.Add();
                var xlSheet = xlBook.Worksheets(1);
                for (var y=0;y<targetTable.rows.length;y++) // targetTable=id of the table
                {
                    for (var x=0;x<targetTable.rows(y).cells.length;x++)
                    {
                        xlSheet.Cells(y+1,x+1)=targetTable.rows(y).cells(x).innerText;
                    }
                }   
                xlObj.Visible=true;
                document.write("The table contents are opened in a new Excel sheet.");//Print on webpage 
            }
    </script>
    </head>
    <body>  
    <input type="button" value="Open table in Excel!" onclick="saveAsXLS()"/> 
    </body>
    

    此代码在 IE6 中测试,使用 ActiveXObject 控件。

    • 我在这里使用的表格是 2x2 的,各个内容分别映射到 Excel 表中。
    • 与 .doc 版本不同,这不会将文件保存在客户端系统中。它使用表格内容打开应用程序,客户端必须保存它。

    希望这有助于回答您的问题。如果您遇到任何问题,请让我知道。

    和平。

    【讨论】:

    • 这看起来很有希望。我在 ie7 中尝试过,但出现以下错误。我一会儿用 ie6(我的目标)试试,结果告诉你:img11.imageshack.us/img11/8444/capturatx.png 错误信息是:原子化服务器无法创建对象
    • 此代码如果在本地运行[没有服务器环境],则可以正常工作。要使其在“服务器”环境中工作,您需要更改一些安全设置以允许在您的服务器系统中创建 ActiveXObject。点击工具>Internet选项>安全选项卡>自定义级别>确保为“下载签名和未签名的activeX控件”选择了“提示”。然后在运行代码时你会得到一个提示。如果这没有帮助,请尝试更改其他相关的 activeX 选项。但请确保您有更新的防病毒程序 b4 更改安全设置,以防万一出现异常情况。 :p
    • 我将其作为本地 html 文件运行,参见图片:img11.imageshack.us/img11/8444/capturatx.png
    • 哇!我想如果我不这样做,js-object 将变得未定义。我可以处理它并说“您需要安装 MS-Office 才能将其保存为 excel”之类的内容...... grrrreat!!!!谢谢冲
    【解决方案3】:

    根据您的浏览器支持要求,您可以使用data URIs

    概念验证核心(在 Firefox 3.5.3 中测试):

    document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
    function extract(){
      return document.getElementById('content').innerHTML; 
    }
    function dataURI(s){
      return 'data:application/vnd.ms-excel;base64,' + encode64(s);
    }
    document.write('<a href="' + dataURI(extract()) + '">open</a>');
    

    我从在线示例中提取了 base 64 编码/解码。小心:我抓到的那个包括一个在 base 64 编码之前的 URI 编码,这让我有一段时间搞砸了。

    【讨论】:

    【解决方案4】:

    您正在接近我认为的答案。问题是'document.open(...)'可以only take standard mime-types such as 'text/html', 'text/plain' and a few others

    因此,您的代码应该是:

    <script>
        document.write("<div id='content'><table><tr><td>Hola</td><td>Adios</td></tr></table></div>");
        function saveAs(){
            var sMarkup =  document.getElementById('content').innerHTML; 
            var oNewDoc = document.open('text/html');        
            oNewDoc.write( sMarkup + "<hr>" );
            oNewDoc.close();
        }
    </script>
    
    <input type="button" value="Save as" onClick="saveAs()"/>
    

    希望这会有所帮助。

    【讨论】:

      【解决方案5】:

      $(function(){
          $('.bbutton').click(function(){
              var url='data:application/vnd.ms-excel,' + encodeURIComponent($('#tableWrap').html() )
              location.href=url
              return false
          })
      })
      .table{background:#ddd;border:1px solid #aaa;}
      .table thead th{border-bottom:1px solid #bbb;}
      .table tr td{background:#eee;border-bottom:1px solid #fff;
        border-left:1px solid #ddd;text-align:center;}
      .table tr:hover td{background:#fff;}
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <div id='tableWrap'><table style='width:98%;box-shadow:none;' class='table'>
      <thead><th>id</th><th>Name</th><th>Address</th></thead>
        <tr><td>1</td><td>Jyoti Telecom Services</td><td>http://www.tsjyoti.com</td></tr>
        <tr><td>2</td><td>Recharge</td><td>http://recharge.tsjyoti.com</td></tr>
        <tr><td>3</td><td>Bhuri Bharaj</td><td>http://bhuribharaj.tsjyoti.com</td></tr>
        </table></div>
      
      <p>Your download's ready as Excel Sheet <a href='#'class='bbutton'>Click Here for download</a></p>

      【讨论】:

        【解决方案6】:

        如果它只是一个报告,您可以使用服务器端 JavaScript 来生成它,然后使用您需要的任何 MIME 类型来提供它...

        【讨论】:

        • (...从而避免往返。)
        • 确实如此。你能指出我对服务器端javascript的正确方向吗?我不知道。
        • 你的服务器是什么平台?
        • 我从未使用过它,但 SpiderMonkey (mozilla.org/js/spidermonkey) 会让你从命令行 (blog.ianbicking.org/jslint-command-line.html) 运行 JS。我想您可以将 SpiderMonkey 设置为服务器端脚本的处理程序。如果你想要一个更端到端的包,还有 Jaxer。
        【解决方案7】:

        我不认为将您的 html 发送到服务器是一个棘手的解决方案。你只需要记住给你的用户一个链接来下载这个文件。这可以使用传统的 POST,甚至使用 AJAX 来完成。这取决于您希望用户如何与您的页面进行交互。

        使用传统的帖子,您可以将所有 html 内容放在页面中隐藏的输入类型的 value 属性中,命名为“html_content”或类似名称,当用户单击“保存”按钮时,您将发送您的用户到另一个带有链接的页面做文件。您将 html 发送到服务器,脚本在文件系统中创建一个具有唯一名称的文件,并返回一个下载链接。

        使用 AJAX,您只需执行 AJAX POST 传递此变量,然后您的脚本返回一个下载链接,然后您将其动态放入您的 html 中 - 无需重新加载您的页面,就像它是“仅客户端”。

        无论哪种方式,您都将返回一个指向您刚刚在文件系统中创建的资源的链接,该链接带有 html 扩展名。请记住在您的服务器中为每个生成的文件生成唯一名称以避免冲突。

        请注意,尽管在 IE 6 中使用 innerHTML(我不知道这是 IE 家族行为还是大约 6 版本)会将所有标签大写并从属性中删除引号。如果您打算在 html 中进行一些后期处理,请小心。

        我不知道 jQuery 或其他 JS 库在这种情况下的表现如何。不过我建议使用它,他们有大量的浏览器兼容性检查来抽象我们使用的所有这些 hack。

        【讨论】:

        • Obrigado GmonC。实际上没有必要将内容保存在文件系统中。相同的请求可以生成内容,并通过将 mime-type 设置为:'application/vnd.ms-excel' 我可以让客户端将内容视为 excel。我会尽量避免(如果可能的话)是来回往返,因为内容可能已经很大了。我已经选择了一个替代方案,但我认为我会将此版本用于非 ie 浏览器。
        • Obrigado 的解释。我现在明白,如果文件太大,那将是浪费时间。它会起作用,但它不是最佳解决方案。仍然需要非 ie 浏览器。现在你需要在你的 js 中创建一个条件,“如果不是,即做服务器方法,否则下载 excel”。祝你好运!
        【解决方案8】:

        这是我的代码,用于将 JavaScript 生成的内容[客户端]以 MSWord[.doc] 格式保存到本地 C: 驱动器。

        <script>
        
            document.write("<div id='content'><table><tr><td>Holaa</td><td>Adiosa</td></tr></table></div>"); 
            function saveAs()
                {
                    var wordObj=new ActiveXObject("Word.Application");
                    var docText;
                    var obj;
                    var textToWrite = document.getElementById('content').innerHTML;
                    if (wordObj != null)
                    {
                        wordObj.Visible = false;
                        wordDoc=wordObj.Documents.Add();
                        wordObj.Selection.TypeText(textToWrite);
                        wordDoc.SaveAs("C:\\Eureka.doc");
                        wordObj.Quit();
                        document.write("The content has been written to 'C:\\Eureka.doc'");//Print on webpage 
                    }
                }
        </script>
        
        <body>
        
        <input type="button" value="Save in C:" onclick="saveAs()"/> 
        
        </body>
        

        我很快就解决了您的问题并想出了这段代码。希望我正确理解了您的问题。

        我的代码中的约束是

        • 文件格式是 .doc 而不是 .xls。
        • 其次,文件保存在静态位置,而不是用户指定的位置[可以优化]。
        • 而且,代码使用 ActiveX,我没有检查在服务器端环境中的工作情况。

        这些需要在即将发布的版本中解决。 (:

        和平。

        【讨论】:

        • 很高兴知道我在正确的道路上。是的,我正在努力解决这个问题(.xls 格式)。将很快发布代码。
        • 请在此处查看我更新后的代码以打开 xls 格式的表格:stackoverflow.com/questions/1479020/…
        【解决方案9】:

        您的 javascript AJAX 是从服务器获取 document.writeln() 内容,还是在向用户提供页面时已经生成该内容?因为如果是前者,我认为您没有理由不能在您使用的任何服务器端技术的会话中保存任何变量/查询,然后从这些技术中生成纯文本内容。否则,你必须按照上面航海者的建议。

        【讨论】:

        • 前者。我不想生成纯文本版本的原因是因为虽然它是可行的,但很可能 a)它们与 javascript 版本不同步(添加列、进行一些计算等必须在双方都进行更改js 和服务器端) b) js 库正是用来避免我们手动进行所有格式化。
        【解决方案10】:

        由于您使用的是 Ext JS,您可能有一个向网格提供数据的 Store 对象?您应该能够通过浏览 Store 提取所需的数据,然后按照您想要的方式对其进行格式化。我认为从生成的 HTML 中抓取数据并不理想。

        从网格中获取所需数据并将其格式化为文本后,您可以将其发布到后端以启动下载(使用 Content-Disposition:附件等)

        如果您不关心跨浏览器,您还可以使用 data: URL 方案来启动下载,而无需涉及后端。

        【讨论】:

        • 我宁愿在进入之前生成表服务器端。但这正是我想要避免的。
        【解决方案11】:

        这个插件可以完成这项工作。在 IE、FF 和 Chrome 上测试。 https://github.com/dcneiner/Downloadify

        【讨论】:

          猜你喜欢
          • 2015-08-14
          • 2010-11-17
          • 1970-01-01
          • 2011-02-23
          • 1970-01-01
          • 2011-11-11
          • 2014-12-04
          • 1970-01-01
          相关资源
          最近更新 更多