4

私は次の状況にあります:

データの整合性をチェックするように設計されたさまざまなPHPスクリプトを実行するために、社内サーバーに一連のCronジョブを設定しました。各PHPスクリプトは、会社のデータベースにクエリを実行し、返されたクエリデータを1つ以上を含むHTMLファイルにフォーマットしてから、HTMLファイルを<tables>添付ファイルとして複数のクライアントの電子メールにメールで送信します。私の経験から、ほとんどのPHPスクリプトは少数のテーブルのみでHTMLファイルを生成しますが、約30のテーブルでHTMLファイルを作成するPHPスクリプトがいくつかあります。HTMLを使用すると、ブラウザウィンドウで一度に多くのテーブルを簡単に表示できるため、これらのスキャンの配布形式としてHTMLファイルが選択されています。

クライアントがHTMLファイルのテーブルをCSVファイルとしてダウンロードする機能を追加したいと思います。テーブルデータに基づいてデータの整合性の問題が疑われる場合、クライアントがこの機能を使用することを期待しています。問題のテーブルを取得し、データをCSVファイルにエクスポートして、さらに調査できることが理想的です。

データをCSV形式にエクスポートする必要があるのはクライアントの裁量であり、どのテーブルが精査されるかは予測できず、断続的に使用されるため、すべてのテーブルにCSVファイルを作成したくありません。

通常、CSVファイルの作成はそれほど難しくありません。JavaScript/ jQueryを使用してDOMトラバーサルを実行し、サーバー呼び出しまたはフラッシュライブラリを使用してCSVファイルデータを文字列に生成し、ダウンロードプロセスを容易にします。しかし、私には1つの制限的な制約があります。それは、HTMLファイルが「ポータブル」である必要があるということです。

クライアントがHTMLファイルを取得して、会社のイントラネットの外部でデータの分析を実行できるようにしたいと思います。また、これらのHTMLファイルはアーカイブされる可能性が高いため、エクスポート機能をHTMLファイルに「自己完結型」にすることは、前述の2つの理由から非常に望ましい機能です。

HTMLファイルからのCSVファイル生成の「ポータブル」制約は次のことを意味します。

  1. サーバーに電話をかけることができません。つまり、すべてのファイル生成はクライアント側で行う必要があります。

  2. 電子メールに添付された単一のHTMLファイルに、CSVファイルを生成するためのすべてのリソースが含まれている必要があります。これは、jQueryまたはフラッシュライブラリを使用してファイルを生成できないことを意味します。

明らかなセキュリティ上の理由から、JavaScriptを使用したディスクへのファイルの書き込みはどのブラウザでもサポートされていないことを理解しています。ユーザーの知らないうちにファイルを作成したくありません。メモリ内のJavaScriptを使用してファイルを生成し、メモリからファイルを「ダウンロード」するようにユーザーに促したいと思います。

CSVファイルをURIとして生成することを検討しましたが、私の調査とテストによると、このアプローチにはいくつかの問題があります。

  • ファイルのURIはIEではサポートされていません(ここを参照

  • FireFoxのURIは、ランダムなファイル名で.partファイルとしてファイルを保存します

辛いことですが、IE<=v9がファイルのURIを作成しないという事実を受け入れることができます。JavaScript DOMトラバーサルがデータをコンパイルした後、Chrome、Firefox、SafariがURLを作成してCSVファイルをダウンロードするセミクロスブラウザーソリューションを作成したいと思います。

私の例の表:

<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>

私の例の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>

上記のサンプルテーブルをCSVファイルとしてダウンロードできるソリューションの例を探しています。

  • URIを使用する
  • <button>またはを使用して<a>
  • コードは、FireFox、Safari、Chromeの最新バージョンで説明されているように機能します
  • AND(1. OR 2.):
      • ユーザーはファイルを保存するように求められます
      • ユーザーは「名前を付けて保存」を右クリックする必要はありません
      • ファイルをデフォルトのブラウザ保存ディレクトリに自動的に保存します
      • デフォルトのファイル名は、ファイル拡張子が.csvのテーブルの名前です。

<script>DOMトラバーサル関数を使用してタグを追加しましたdoSomething()doSomething()私が必要とする本当の助けは、関数内で必要なものにURIをフォーマットすることです。アプローチ#2(私のコードを参照)は最も有望なようです。

ステートメントに証拠が提示されている場合、HTMLとJavaScriptのみを使用して目的の機能を実現することは不可能であることを喜んで受け入れます。ブラウザのドキュメント、DOM標準、JavaScript / ECMAscriptのドキュメント、または不可能を示す論理的な反例など。

そうは言っても、解決策が少しハックであっても、URIの経験が豊富で経験豊富な人から解決策が得られると思います。

4

3 に答える 3

3

IEに関してはIE10+のみをサポートすることを気にしない限り、 FileSaver.jsを使用してください。CSVを生成し、それをBLOBに追加してから、BLOBに追加できますsaveAs()。保存したファイルのファイル名は、<a download>Chromeなどのをサポートするブラウザでのみ保存できます。

于 2012-09-13T16:04:47.090 に答える
1

コメントで「個別のHTMLファイルとCSVファイルを作成する必要はない」と述べていますが、この場合、基本的な必要性は2つの形式でデータを提供することです。データの2つのコピーを作成することは不合理な制約ではありません。繰り返しますが、あなたが求めていることは実現可能ではありません。

私があなたの問題に想像できる最も近い解決策は、CSVデータをHTMLファイルにパッケージ化し(ディスプレイを介して:divなどなし)、ロード時にJavaScriptを使用して動的にHTMLテーブルにデータを入力することです。レコードセットが大きい場合、これは遅くなりますが、コピーして貼り付けるためのCSVテキストを表示および選択するためのボタンを追加するのは簡単です。エレガントではない?ええ、ごめんなさい。HTMLが交換形式ではないのには理由があります。

そうは言っても、表形式のデータをPDFにパッケージ化し、その中にCSVを添付ファイルとして含めることができます。

于 2012-09-01T22:34:41.357 に答える
-1

電子メールに添付された単一のHTMLファイルに、CSVファイルを生成するためのすべてのリソースが含まれている必要があります。これは、jQueryを使用できないことを意味します

これは虚偽の陳述です。サーバーを呼び出さずに単一のHTMLファイルでjQuery機能を使用する場合は、縮小されたjQueryライブラリをHTML自体にコピーして貼り付けるだけです。一度に数百通のメールを送信しない限り、各HTMLファイルが32K大きくなりますが、これはひどいことではありません。

したがって、jQueryに精通していて、ページ上のデータをリファクタリングするためにjQueryを使用することに慣れている場合は、jQueryを自由に使用してください。自動作成されたHTMLにはjavascript配列のデータがあり、ページの読み込み時にテーブルが作成されることをお勧めします。次に、ユーザーがCSVオプションをクリックすると、それをクリアしてリファクタリングできます。

var data = {
  title: 'NameOfTable',
  headers: ['VEN_PK', 'VEN_CompanyName', 'VEN_Order'],
  data: [
    ['1', 'Brander Ranch' 'Beef'],
    ['2', 'Super Tree Produce' 'Apples'],
    ['3', 'John\'s Distilery' 'Beer']
  ] 
}
$(document).ready(function() {
  var html = '<table>';
  html += '<thead>';
  html += '<tr><th style="text-align:center;" colspan="' + data.headers.length +'">' + data.title + '</th></tr>';
  html += '</thead><tbody>';
  html += '<tr class="resultheader">';
  for (i in data.headers) {
    html += '<td>'+data.headers[i]+'</td>';
  }
  html += '</tr>';
  for (i in data.data) {
    var row = data.data[i];
    html += '<tr>';
    for (j in row) {
      html += '<td class="resultfield">'+row[j]+'</td>';
    }
    html += '</tr>';
  }
  html += '</table>';
  $('#container').html(html);
});

function showCSV() {
   var csv = '';
   for (i in data.headers) {
     csv += data.headers[i] + ',';
   }
   csv += "\n";
   for (i in data.data) {
     var row = data.data[i];
     for (j in row) {
       csv += row[j] + ',';
     }
     csv += "\n";
   }
   $('#container').html(csv);
}
于 2012-09-14T16:38:40.797 に答える