質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

962閲覧

FILE APIでCSVファイルを書き出したいですが、反応がありません。

lovelydai

総合スコア38

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2017/12/06 11:28

こんにちは、いつもお世話になっております。

CSVのインポートとエクスポート機能を作っています。
FILE APIを使ってローカルからファイル中身を読み取ってDBに入れるインポートと、DBにあるデータをCSVファイルに吐き出すエクスポートを実装しようとしてます。インポートはなんとか作り、今はエクスポートの方を使っています。

やりたいのは、Cakehphp3のコントローラーからDBの情報を配列で作り、Ajaxで渡してFILE APIを用いてローカルにダウンロードさせることです。

https://qiita.com/wadahiro/items/eb50ac6bbe2e18cf8813

このリンク先のサンプル2番目の感じです。サンプルのテストは上手く行きましたので、以下のように書いてみましたが、ファイルが生成されず、そのまま最後まで走ってしまいます。
デバッグしてみたら、blobオブジェクトが怪しいかな、と思います。ファイル名やJSON,配列のデータは思い通りに取れていますが、なぜかmsSaveBlob, msSaveOrOpenBlob, else(chrome等用)までひっかからずパースしてしまいます。
どこがおかしいのか、怪しいところや何かヒントがありましたら教えてください。
ソースコードとDebugした画面を添付します。宜しくお願い致します。

値はファイル生成前まではちゃんと取れています。

コンソールに配列とCSVデータを出力してみましたが、問題なさそうです。

コントローラー側では、DBからデータを出してそれをSerializeするだけです。

public function export() { if($this->request->is('ajax')) { $customer_idx = $this->Auth->user('customer_idx'); $sections = $this->Section->find()->where(['customer_idx' => $customer_idx]) ->select(['section_idx','year','customer_idx','section_code','section_name','section_short','memo','is_used','deleter','deleted']) ->epilog('FOR UPDATE') ->toArray(); if(!empty($sections)) { // success $results = $sections; $this->Flash->success(__('データベースからエクスポートに成功しました。')); } else { //failed $results = null; throw new exception($e); $this->log($e); $this->Flash->error(__('エクスポート失敗[DBデータエラー](E30005)')); } $this->set('result', $results); $this->set('_serialize', ['result']); } }

クライアントの方は、ファイル名を入力してもらい、そのファイル名でCSVファイルを生成したいです。<a>タグのdownload
プロパティ使うということでしたので、CSV出力ボタンを押すと、ファイル名を.arrで追加する形にしました。

HTML

1<div class="form-group"> 2  <div class="col-lg-12"> 3    <?= $this->Form->control('filename', ['class' => 'form-control','label' => 'CSVファイル名', 'type' => 'text', 'required' => 'required', 'id'=>'filename']); ?> 4  </div> 5</div> 6 7 <div class="form-group" align="center"> 8 <?= $this->Html->link( 9 '戻る', $referer, 10 ['class' => 'btn btn-success btn-sm', 'type' => 'button'] 11 ); ?> 12 13 <a id="download" href="#"><button type="button" class="btn btn-primary btn-sm">CSV出力</button></a>

スクリプトの方はこんな感じです。

<script type='text/javascript'> $('#download').on('click', function(e){ // ファイル名をAタグのDownload属性で追加 e.preventDefault(); var filename = $('#filename').val() + ".csv"; $('#download').attr('download',filename); if(window.File && window.FileReader && window.FileList && window.Blob) { if($('#filename').val()=='') { alert('CSVファイル名は必ず入力してください。'); return false; } if(!confirm('CSVファイルにマスタ情報の出力を行います。本当によろしいですか?')) { alert('CSVファイル出力をキャンセルしました。'); return false; } else { $.getJSON('../section/export', null, function(data,status){ // phpから連想配列をとってくる if(status) { var contents = []; var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); // UTF-8のBOMコード for(var key in data.result) { contents[key] = []; //配列の要素数を指定する contents[key] = Object.values(data.result[key]); // 連想配列を配列にする。 } 'use strict'; var csvContents = CSV.stringify(contents); // CSV化する。 // データをファイルとして作る var blob = new Blob([bom,csvContents], { type : 'text/csv;charset=utf-8;' }); if (window.navigator.msSaveBlob) { window.navigator.msSaveBlob(blob, filename); window.navigator.msSaveOrOpenBlob(blob, filename); } else { $('#download').attr('href',(window.URL || window.webkitURL).createObjectURL(blob, {type: "application/octet-stream"})); }   } else { alert('DBエラー'); return false; } })

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

defghi1977

2017/12/06 11:34

コードをスクリーンショットで貼り付けるのは可読性の面からおすすめできません. コピペでいいのでコードそのものを掲載して下さい.
defghi1977

2017/12/06 11:39

「text/csv;charset=utf-8;」の末尾の;が要らない気がする.「text/csv;charset=utf-8」だと思う
lovelydai

2017/12/06 23:53

回答ありがとうございます。コードは下の方にあります、スクリーンショットはデバッグの結果を見ていただくために添付したものです。
defghi1977

2017/12/07 04:00

「text/csv;charset=utf-8;」のところを「text/plain」に変えたら動きませんか?csvはブラウザで直接取り扱う形式ではないので気になります.
guest

回答2

0

自己解決

解決しました。
原因は、やはりイベントの着火タイミングでした。
aリンクのボタンを押してイベントを作り、サーバーからオブジェクトを受け取ってきた時には、もうイベントが終わってしまったのでファイルダウンロードイベントが上手く動かなかったというか、着火されなかったようです。

解決策は、まずaタグのDownloadのコピーをhiddenタイプで作り、hrefのcreatedObjectURLを作った後にclick()イベントを明記しておくことでした。
これでファイルはダウンロードされるようになりました。

また、もう一つの問題があり、それは中身に入れる内容のフォーマットでした。
ということで、何とか解決できましたので、そのソースコードを共有致します。

HTML

1<!--他の部分は省略です、リンクタグでイベントを作るところです。--> 2<a id="download" href="#"><button type="button" class="btn btn-primary btn-sm">CSV出力</button></a> 3<a id="download_hidden" href="#"></a>

Javascript

1 $.getJSON(urlPath, 2 null, 3 function(data,status) 4 { 5 if(status) 6 { 7 var filename = $('#filename').val() + ".csv"; 8 $('#download_hidden').attr('download',filename); 9 10 var contents = []; 11 var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); // UTF-8のBOMコード 12 13 for(var key in data.result) 14 { 15 contents[key] = []; //配列の要素数を指定する 16 // オブジェクト値を文字列に変換する。 17 18 var temp_var = JSON.stringify(Object.values(data.result[key]), 19 // Nullがある場合は、””に変える。 20 function(key, value) 21 { 22 if (value === null || value =='') 23 { 24 return '""'; 25 } 26 return value; 27 } 28 ); 29 // 文字列配列をJSONとして加工する。 30 contents[key] = JSON.parse(temp_var); 31 } 32 33 // File APIのBlobのパラメータに投げるために形を整形する。 34 var csvContents = contents.map(function(l){return l.join(',')}).join('\r\n'); 35 console.log("cvsContents = ",csvContents); 36 37 // データをファイルとして作る 38 var blob = new Blob([bom,csvContents], { type : 'text/csv' }); 39 40 if (window.navigator.msSaveBlob) 41 { 42 window.navigator.msSaveBlob(blob, filename); 43 // msSaveOrOpenBlobの場合はファイルを保存せずに開ける 44 window.navigator.msSaveOrOpenBlob(blob, filename); 45 } 46 else 47 { 48 var linkObj = document.getElementById("download_hidden"); 49 linkObj.href = window.URL.createObjectURL(blob); 50 linkObj.click(); 51 } 52 } 53 window.URL.revokeObjectURL(blob); 54 })

投稿2017/12/07 10:19

lovelydai

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

すみません誤って回答しました・・・。

投稿2017/12/07 05:21

編集2017/12/07 05:23
rnosh

総合スコア171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問