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

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

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

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

iPhone 6

iPhone 6は、2014年に発売されたアップル社のスマートフォンです。画面サイズは4.7インチあり、A8コアチップとM8モーションコプロセッサを搭載しています。

Q&A

解決済

1回答

2592閲覧

iPhoneブラウザにてexcelファイルが正常にダウンロードできません【JavaScript】

gemknight

総合スコア13

JavaScript

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

iPhone 6

iPhone 6は、2014年に発売されたアップル社のスマートフォンです。画面サイズは4.7インチあり、A8コアチップとM8モーションコプロセッサを搭載しています。

0グッド

1クリップ

投稿2020/01/23 10:47

編集2020/01/24 01:25

前提・実現したいこと

各種スマートフォンのブラウザにて加速度を測定して測定結果をexcelファイルで出力し、そのままexcelアプリで閲覧したいです。

発生している問題

環境はiPhone6(iOS12.44)です。
safariではunknown、chromeではdocumentとファイル名が書き換えられます。
(拡張子も無くなりますがパソコン上で拡張子を変更すると無事に閲覧できます)
そのためプログラムで設定した名前でダウンロードすることができません。

該当のソースコード

JavaScript

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8" /> 5 <title>sample1</title> 6 <script src="js/xlsx.full.min.js"></script> 7 <script src="js/FileSaver.min.js"></script> 8</head> 9<body> 10 <input type="button" id="xlsx" value="Excelファイル出力" onclick="func1()"> 11 <script language="javascript" type="text/javascript"> 12 // 出力するオブジェクト(Array) 13 var array1 = 14 [ 15 ["apple", "banana", "cherry"], 16 [1, 2, 3] 17 ]; 18 19 // SheetをWorkbookに追加する 20 // 参照:https://github.com/SheetJS/js-xlsx/issues/163 21 function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ { 22 var n = opts && opts.sheet ? opts.sheet : "Sheet1"; 23 var sheets = {}; sheets[n] = sheet; 24 return { SheetNames: [n], Sheets: sheets }; 25 } 26 27 // ArrayをWorkbookに変換する 28 // 参照:https://github.com/SheetJS/js-xlsx/issues/163 29 function aoa_to_workbook(data/*:Array<Array<any> >*/, opts)/*:Workbook*/ { 30 return sheet_to_workbook(XLSX.utils.aoa_to_sheet(data, opts), opts); 31 } 32 33 // stringをArrayBufferに変換する 34 // 参照:https://stackoverflow.com/questions/34993292/how-to-save-xlsx-data-to-file-as-a-blob 35 function s2ab(s) { 36 var buf = new ArrayBuffer(s.length); 37 var view = new Uint8Array(buf); 38 for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; 39 return buf; 40 } 41 42 function func1() { 43 // 書き込み時のオプションは以下を参照 44 // https://github.com/SheetJS/js-xlsx/blob/master/README.md#writing-options 45 var write_opts = { 46 type: 'binary' 47 }; 48 49 // ArrayをWorkbookに変換する 50 var wb = aoa_to_workbook(array1); 51 var wb_out = XLSX.write(wb, write_opts); 52 53 // WorkbookからBlobオブジェクトを生成 54 // 参照:https://developer.mozilla.org/ja/docs/Web/API/Blob 55 var blob = new Blob([s2ab(wb_out)], { type: 'application/octet-stream' }); 56 57 // FileSaverのsaveAs関数で、xlsxファイルとしてダウンロード 58 // 参照:https://github.com/eligrey/FileSaver.js/ 59 saveAs(blob, 'myExcelFile.xlsx'); 60 } 61 </script> 62</body> 63</html>

(こちらのソースコードでも同じ挙動が起こります)
↓参考にしたサイト
https://techacademy.jp/magazine/21073
(jsファイル等は最新バージョンをダウンロードしており、iPhone6以外では正常な動作を確認しています)

試したこと

iPhone7(iOS13.3)とAndroidで試した場合は問題なくファイルをダウンロードできました。

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

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

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

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

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

Lhankor_Mhy

2020/01/24 01:14

filesaver.js の最新バージョンは2.0.1の様ですが、ご提示のリンク先は1.3.8でした。 その辺に原因はないのですか?
gemknight

2020/01/24 01:18

jsファイル等は最新バージョンで適用しています。iPhone6以外では正常に動作しているため、原因はOS側だと考えています。
gemknight

2020/01/24 01:27

ソースコードを追記しました。変更部分はjsファイルの指定部分だけになっています。
gemknight

2020/01/24 01:54

ありがとうございます。多分これが原因だと思います。 英語が苦手なので確認させてもらうようで恐縮ですが、iOS12.4以前のsafari及びchromeブラウザはファイルダウンロードをサポートしていないという認識であっていますか?
kyoya0819

2020/01/24 02:53 編集

横から失礼します。正しい認識は、 IEの全バージョンと iOS12.4以前の全てのブラウザ その他、パソコンにおける赤字のバージョン が非対応であるということです。。
Lhankor_Mhy

2020/01/24 03:29

Filesaver.jsのコードを読みましたので、回答に書きますね。
guest

回答1

0

ベストアンサー

補足依頼コメントに書いた通り、iOS13からはdownload属性に対応したのが処理結果の違いの原因です。

データURIスキームでダウンロードしたファイルには通常のリンクからダウンロードしたファイルと違ってファイル名がない。保存するときのファイル名はMIMEタイプごとに用意されたデフォルトの物となる。ただし、HTML5ではa要素にダウンロード時のファイル名を指定できるdownload属性が追加されたため、一部のブラウザではこの問題は解決した。

Data URI scheme - Wikipedia

 
さて、iOS12以前はどのように処理されているかについてですが。
Filesaver.jsのコードを抜粋しますと、

js

1var saveAs = _global.saveAs || ( 2 3//... 4 5 // Use download attribute first if possible (#193 Lumia mobile) 6 : 'download' in HTMLAnchorElement.prototype 7 ? function saveAs (blob, name, opts) { 8 9//... 10 11 } 12 13 // Use msSaveOrOpenBlob as a second approach 14 : 'msSaveOrOpenBlob' in navigator 15 ? function saveAs (blob, name, opts) { 16 17//... 18 19 } 20 21 // Fallback to using FileReader and a popup 22 : function saveAs (blob, name, opts, popup) { 23 24//... 25 26 }

となっており、download属性があればそれを使い、なければmsSaveOrOpenBlobを使い(たぶんIE10、11対策)、そうでなければFileReaderを使う(たぶんiOS対策)、というものです。

FileReaderを使う部分のコードを読むと、.readAsDataURL()で読み込んだデータURLに書かれているMIMEタイプ文字列を直接attachment/fileに書き換えるという処理をしておりなかなか興味深いのですが、それはそれとして、その部分の処理ではファイル名を表すname引数が一切参照されていないことがわかります。

そういうわけで、これが原因であると思われ、その内容を考えるとクライアント側のコードでは対応が難しいかと思います。

投稿2020/01/24 03:47

編集2020/01/24 03:51
Lhankor_Mhy

総合スコア35867

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

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

gemknight

2020/01/24 07:04

無事問題の原因が把握できて助かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問