HTML客户端可移植文件生成 - 无需外部资源或服务器调用 [英] HTML client-side portable file generation - no external resources or server calls

查看:70
本文介绍了HTML客户端可移植文件生成 - 无需外部资源或服务器调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:

我在内部公司服务器上设置了一系列Cron作业,以运行各种旨在检查数据完整性的PHP脚本。每个PHP脚本查询公司数据库,将返回的查询数据格式化为包含一个或多个< tables> 的HTML文件,然后将该HTML文件邮寄到多个客户端电子邮件中一个附件。根据我的经验,大多数PHP脚本只生成仅包含少量表格的HTML文件,但是有几个PHP脚本可以创建包含大约30个表格的HTML文件。已经选择HTML文件作为这些扫描的分发格式,因为HTML可以很容易地在浏览器窗口中一次查看多个表。



我想添加功能让客户端以CSV文件的形式下载HTML文件中的表格。我预计客户在怀疑基于表数据的数据完整性问题时使用此功能。对于他们来说,这将是理想的选择,将数据导出到CSV文件,然后进一步研究。由于需要将数据导出为CSV格式由客户自行决定,对于哪些表格将进行详细审查并且间歇性地使用我做的事情是不可预知的。

不希望为每个表格创建CSV文件。



通常,创建CSV文件不会太困难,使用JavaScript / jQuery预制DOM遍历和使用服务器调用或闪存库将CSV文件数据生成为字符串以促进下载过程;但我有一个限制性约束:HTML文件需要便携。



我希望客户能够获取他们的HTML文件并对公司内部网之外的数据进行预分析。此外,这些HTML文件很可能会被归档,因此,使HTML文件中的导出功能独立存在是前两个原因中非常理想的功能。

从HTML文件生成CSV文件的便携约束表示:


  1. 我无法拨打服务器电话。这意味着 ALL 文件生成必须在客户端进行。


  2. 我希望附加到电子邮件的单个HTML文件包含所有资源来生成CSV文件。这意味着我不能使用jQuery或Flash库来生成文件。


我知道,出于明显的安全原因,任何浏览器都不支持使用JavaScript将文件写入磁盘。我不想在没有用户知识的情况下创建文件;我想在内存中使用JavaScript生成文件,然后提示用户从内存中下载文件。



我已经研究过将CSV文件生成为然而,根据我的研究和测试,这种方法存在一些问题:



尽管我很痛苦,但我可以接受IE< = v9不会为文件创建URI的事实。我希望创建一个半跨浏览器解决方案,在该解决方案中,Chrome浏览器,Firefox和Safari会创建一个URI,以在JavaScript DOM遍历编译数据后下载CSV文件。



我的示例表:

 < table> 
< thead class =resulttitle>
< tr>
NameOfTheTable< / th>
< / tr>
< / thead>
< tbody>
< tr class =resultheader>
< td> VEN_PK< / td>
< td> VEN_CompanyName< / td>
< td> VEN_Order< / td>
< / tr>
< tr>
< td class ='resultfield'> 1< / td>
< td class ='resultfield'> Brander Ranch< / td>
< td class ='resultfield'>牛肉< / td>
< / tr>
< tr>
< td class ='resultfield'> 2< / td>
< td class ='resultfield'>超级树制作< / td>
< td class ='resultfield'>苹果< / td>
< / tr>
< tr>
< td class ='resultfield'> 3< / td>
< td class ='resultfield'> John's Distilery< / td>
< td class ='resultfield'> Beer< / td>
< / tr>
< / tbody>
< tfoot>
< tr>
< td colspan =3style =text-align:right;>
< button onclick =doSomething(this);>汇出至CSV档案< / button>< / td>
< / tr>
< / tfoot>
< / table>

我的JavaScript示例

 < script type =text / javascript> 
函数doSomething(inButton){

/ *定位元素* /
var table = inButton.parentNode.parentNode.parentNode.parentNode;
var name = table.rows [0] .cells [0] .textContent;
var tbody = table.tBodies [0];

/ *通过DOM遍历创建CSV字符串* /
var rows = tbody.rows;
var csvStr =; (var j = 0; j ) b csvStr + = rows [i] .cells [j] .textContent +,;
}
csvStr + =\\\
;
}

/ *临时证明DOM遍历成功* /
alert(Table Name:\ t+ name +\\\
CSV String:\\\
+ csvStr);

/ *在此创建URI!
*(我缺少的代码)
* /

/ *方法#1:从浏览器自动下载
*尝试将浏览器重定向到URI
*并让浏览器将数据作为文件下载
*
*方法不下载CSV数据,但:
*在FireFox下载为randomCharacers.part而不是name.csv
*在没有提示用户且没有正确文件名的情况下在Chrome下载中
*在Safari中打开浏览器中的文件(文本文件)
* /
/ *方法#1代码:
var hrefData =data:text / csv; charset = US-ASCII,+ encodeURIComponent(csvStr);
document.location.href = hrefData;
* /

/ *方法#2:右键另存为链接...
*尝试删除下载按钮
*并将其替换带有锚标签< a>
*表示用户可以用来下载数据
*
*方法有点更好:
*点击链接时:
*在FireFox下载为randomCharacers.part代替name.csv
*在不提示用户的情况下使用Chrome浏览器(使用正确的名称)
*在Safari中打开浏览器中的文件(文本文件)
*
*当在链接上右键单击另存为时:
*在FireFox中提示用户输入文件名:randomCharacers.part
*在Chrome中提示用户输入文件名:download
* In Safari提示用户输入文件名:Unknown
* /
/ *方法#2代码:
var hrefData =data:text / csv; charset = US-ASCII+ encodeURIComponent (csvStr);
var fileLink = document.createElement(a);
fileLink.href = hrefData;
fileLink.type =text / csv;
fileLink.innerHTML =CSV下载链接;
fileLink.setAttribute(download,name +。csv); //用于Chrome
parentTD = inButton.parentNode;
parentTD.appendChild(fileLink);
parentTD.removeChild(inButton);
* /
}
< / script>

我正在寻找一个示例解决方案,可以将上述示例表格作为CSV文件下载:使用URI的
$ b


  • 使用<按钮>的
  • code>或< a>
  • 代码的工作方式与现代版本的FireFox,Safari,& Chrome

  • AND (1. 2.):




    1. 提示用户保存文件

    2. 用户不需要右键另存为



      • 自动将文件保存到默认浏览器保存目录中 带.csv文件扩展名的表的名称





我用DOM遍历函数 doSomething()< script> 。我需要的真正帮助是在 doSomething()函数中将URI的格式设置为我想要的。方法2(看我的代码)似乎最有前途。



我愿意接受我所需的功能是不可能仅使用HTML&如果声明提供证明,则为JavaScript;如浏览器文档,DOM标准,JavaScript / ECMAscript文档或逻辑计数器示例来证明不可能性。这就是说,我认为一个解决方案是可能的,使用URI的更深层次的背景/经验,即使解决方案有点破解。

只要你当涉及到IE时,不要介意只支持IE10 +,请使用 FileSaver.js 。您可以生成CSV并将其附加到Blob,然后 saveAs() blob。您只能在支持<下载> 的浏览器中保存已保存文件的文件名,例如Chrome。


I have the following situation:

I have set up a series of Cron jobs on an internal company server to run various PHP scripts designed to check data integrity. Each PHP script queries a company database, formats the returned query data into an HTML file containing one or more <tables>, and then mails the HTML file to several client emails as an attachment. From my experience, most of the PHP scripts generate HTML files with only a few tables, however there are a few PHP scripts the create HTML files with around 30 tables. HTML files have been chosen as the distribution format of these scans because HTML makes it easy to view many tables at once in a browser window.

I would like to add the functionality for the clients to download a table in the HTML file as a CSV file. I anticipate clients using this feature when they suspect a data integrity issue based on the table data. It would be ideal for them to be able to take the table in question, export the data out to a CSV file, and then study it further.

Because need for exporting the data to CSV format is at the discretion of the client, unpredictable as to what table will be under scrutiny, and intermittently used I do not want to create CSV files for every table.

Normally creating a CSV file wouldn't be too difficult, using JavaScript/jQuery to preform DOM traversal and generate the CSV file data into a string utilizing a server call or flash library to facilitate the download process; but I have one limiting constraint: The HTML file needs to be "portable."

I would like the clients to be able to take their HTML file and preform analysis of the data outside the company intranet. Also it is likely these HTML files will be archived, so making the export functionality "self contained" in the HTML files is a highly desirable feature for the two previous reasons.

The "portable" constraint of CSV file generation from a HTML file means:

  1. I cannot make a server call. This means ALL the file generation must be done client-side.

  2. I want the single HTML file attached to the email to contain all the resources to generate the CSV file. This means I cannot use jQuery or flash libraries to generate the file.

I understand, for obvious security reasons, that writing out files to disk using JavaScript isn't supported by any browser. I don't want to create a file without the user knowledge; I would like to generate the file using JavaScript in memory and then prompt the user the "download" the file from memory.

I have looked into generating the CSV file as a URI however, according to my research and testing, this approach has a few problems:

  • URIs for files are not supported by IE (See Here)

  • URIs in FireFox saves the file with a random file name and as a .part file

As much as it pains me, I can accept the fact the IE<=v9 won't create a URI for files. I would like to create a semi-cross-browser solution in which Chrome, Firefox, and Safari create a URI to download the CSV file after JavaScript DOM traversal compiles the data.

My Example Table:

<table>
    <thead class="resulttitle">
        <tr>
            <th style="text-align:center;" colspan="3">
            NameOfTheTable</th>
        </tr>
    </thead>
    <tbody>
        <tr class="resultheader">
            <td>VEN_PK</td>
            <td>VEN_CompanyName</td>
            <td>VEN_Order</td>
        </tr>
        <tr>
            <td class='resultfield'>1</td>
            <td class='resultfield'>Brander Ranch</td>
            <td class='resultfield'>Beef</td>
        </tr>
        <tr>
            <td class='resultfield'>2</td>
            <td class='resultfield'>Super Tree Produce</td>
            <td class='resultfield'>Apples</td>
        </tr>
        <tr>
            <td class='resultfield'>3</td>
            <td class='resultfield'>John's Distilery</td>
            <td class='resultfield'>Beer</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
          <td colspan="3" style="text-align:right;">
          <button onclick="doSomething(this);">Export to CSV File</button></td>
        </tr>
    </tfoot>
</table>

My Example JavaScript:

<script type="text/javascript">
  function doSomething(inButton) {

    /* locate elements */
    var table = inButton.parentNode.parentNode.parentNode.parentNode;
    var name  = table.rows[0].cells[0].textContent;
    var tbody = table.tBodies[0];

    /* create CSV String through DOM traversal */
    var rows  = tbody.rows;
    var csvStr = "";
    for (var i=0; i < rows.length; i++) {
      for (var j=0; j < rows[i].cells.length; j++) {
        csvStr += rows[i].cells[j].textContent +",";
      }
      csvStr += "\n";
    }

    /* temporary proof DOM traversal was successful */
    alert("Table Name:\t" + name + "\nCSV String:\n" + csvStr);

    /* Create URI Here!
     * (code I am missing)
     */

    /* Approach #1 : Auto-Download From Browser
     * Attempts to redirect the browser to the URI
     * and have the browser download the data as a file
     *
     * Approach does downloads CSV data but:
     * In FireFox downloads as randomCharacers.part instead of name.csv
     * In Chrome downloads without prompting the user and without correct file name
     * In Safari opens the files in browser (textfile)
     */
    /* Approach #1 Code:
       var hrefData = "data:text/csv;charset=US-ASCII," + encodeURIComponent(csvStr);
       document.location.href = hrefData;
     */

    /* Approach #2 : Right-Click Save As Link...
     * Attempts to remove "Download Button"
     * and replace the it with an anchor tag <a>
     * that the user can use to download the data
     *
     * Approach sort of works better:
     * When clicking on the link:
     * In FireFox downloads as randomCharacers.part instead of name.csv
     * In Chrome downloads without prompting the user (uses correct name) 
     * In Safari opens the files in browser (textfile)
     * 
     * When right-click "Save As" on the link:
     * In FireFox prompts the user with filename: randomCharacers.part 
     * In Chrome  prompts the user with filename: "download"
     * In Safari  prompts the user with filename: "Unknown"
     */
    /* Approach #2 Code:
       var hrefData = "data:text/csv;charset=US-ASCII," + encodeURIComponent(csvStr);
       var fileLink = document.createElement("a");
       fileLink.href = hrefData;
       fileLink.type  = "text/csv";
       fileLink.innerHTML = "CSV Download Link";
       fileLink.setAttribute("download",name+".csv"); // for Chrome
       parentTD = inButton.parentNode;
       parentTD.appendChild(fileLink);
       parentTD.removeChild(inButton);
     */
  }
</script>

I am looking for an example solution in which the above example table can be downloaded as a CSV file:

  • using a URI
  • using a <button> or a <a>
  • code works as described in modern versions of FireFox, Safari, & Chrome
  • AND ( 1. OR 2. ):

      • the user is prompted to save the file
      • user does not need to "Right Click Save As"
      • automatically saves the file to default browser save directory
      • the default filename is the name of the table with the .csv file extension

I have added a <script> tag with the DOM traversal function doSomething(). The real help I need is with formatting the URI to what I want within the doSomething() function. Approach #2 (see my code) seem most promising.

I am willing to accept that my desired functionality is impossible to achieve using only HTML & JavaScript if the statement is presented with proof; such as browser documentation, DOM standards, JavaScript/ECMAscript documentation, or a logical counter example demonstrating the impossibility.

That being said, I think a solution is possible from someone with a deeper background/more experience with URIs, even if the solution is a little bit of a hack.

解决方案

As long as you don't mind only supporting IE10+ when it comes to IE, use FileSaver.js. You can generate the CSV and append it to a Blob, and then saveAs() the blob. You will only be able to preserve the filename of the saved file in browsers that support <a download>, like Chrome.

这篇关于HTML客户端可移植文件生成 - 无需外部资源或服务器调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆