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

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

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

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

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

Q&A

解決済

2回答

11135閲覧

Google スプレッドシートの内容をCSV、Shift_JIS形式で直接ローカルにダウンロードしたい

bossapporo

総合スコア11

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

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

1グッド

1クリップ

投稿2019/03/18 18:28

前提・実現したいこと

Googleスプレッドシートの内容をCSV形式で、直接ローカルにダウンロードするスクリプトを書こうとして、
下記の方法を試しました。
https://qiita.com/ayies128/items/315f161bc14c36327fcd

これはこれでうまく行くのですが、文字コードがUTF-8になってしまうので、
Shift_JISにする方法を探しています。

詳しい方、ご教授いただけると助かります。

発生している問題・エラーメッセージ

文字コードの変換はBlobオブジェクトを使い、SetDataFromString()を使ってできるようなのですが、
BlobをGoogle Drive上のファイルとして保存することはできるものの、直接ローカルにダウンロード
しようとすると、うまくShift_JISに変換できません。

該当のソースコード

GoogleAppsScript

1function exportAsCSV() { 2 3 // dialog.html をもとにHTMLファイルを生成 4 // evaluate() は dialog.html 内の GAS を実行するため( <?= => の箇所) 5 var html = HtmlService.createTemplateFromFile("dialog").evaluate(); 6 7 // 上記HTMLファイルをダイアログ出力 8 SpreadsheetApp.getUi().showModalDialog(html, "ファイルダウンロード"); 9} 10 11function getData() { 12 13 // スプレッドシート上の値を二次元配列の形で取得 14 var sheet = SpreadsheetApp.getActiveSheet(); 15 var values = sheet.getDataRange().getValues(); 16 17 // 二次元配列をCSV形式のテキストデータに変換 18 var dataArray = []; 19 for (var i = 0; i < values.length; i++) { 20 dataArray.push(values[i].join(",")); 21 } 22 var dataStr = dataArray.join("\r\n"); // 改行コードは windows を想定 23 24 // Shift_JISなBlobに変換 25 var blob = Utilities.newBlob("", "text/csv", "temp").setDataFromString(dataStr,"Shift_JIS") 26 27 return blob.getDataAsString("Shift_JIS"); //stringにするとUTF-8になってしまうようだ? 28 29 //DriveApp.createFile(blob); //これはちゃんとShift_JISのまま保存される 30 31} 32 33// ファイル名の設定 34function getFileName() { 35 var sss = SpreadsheetApp.getActiveSpreadsheet(); 36 var now = new Date(); 37 var datetime = Utilities.formatDate( now, 'Asia/Tokyo', 'yyyyMMddHHmm'); 38 // スプレッドシート名+プラン名 39 return sss.getName() + '_' + sss.getRangeByName("planName").getValue() + '.csv'; 40} 41

HTML

1 <!-- dialog.html こちらは参考にしたコードそのままです。--> 2<!DOCTYPE html> 3<html> 4 <head> 5 <base target="_top"> 6 <script type='text/javascript'> 7 window.onload = function(){ 8 handleDownload(); 9 } 10 function handleDownload() { 11 // 出力データを GAS から取得する 12 var content = <?= getData(); ?>; 13 var blob = new Blob([ content ], { "type" : "text/csv"}); 14 var link = document.createElement('a'); 15 // ファイル名を GAS から取得する 16 link.download = <?= getFileName(); ?>; 17 link.href = window.URL.createObjectURL(blob); 18 link.click(); 19 // ダイアログを閉じる 20 google.script.host.close(); 21 } 22 </script> 23 </head> 24</html>

試したこと

getDataAsString()で引数なし、"ascii"、"UTF-8"など試しましたがうまく行きませんでした。
getDataAsString()のかわりにgetBytes()を使うと、10進数でデータをダンプしたような文字列がダウンロードされてしまいます。

補足情報(FW/ツールのバージョンなど)

Windows 7 Professional 64bit/Chrome 73.0.3683.75(Official Build) (64 ビット)

Akira_1👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

いくつかある方法の一つとして、ここではGoogle Apps Script側でsjisのblobをbase64に変換し、それをHTML側へ渡してblobに戻してダウンロードさせる方法について提案させていただきます。掲載されているGoogle Apps Script側、HTML側のスクリプトについて、それぞれ一ヵ所を下記のように修正してください。

Google Apps Script側

関数getData()を下記のように変更してください。

From

javascript

1return blob.getDataAsString("Shift_JIS"); //stringにするとUTF-8になってしまうようだ?

To

javascript

1return Utilities.base64Encode(blob.getBytes());

HTML側

関数handleDownload()を下記のように変更してください。

From

javascript

1var blob = new Blob([ content ], { "type" : "text/csv"});

To

javascript

1var blob = new Blob([new Uint8Array([].map.call(atob(content), function(c) {return c.charCodeAt(0)})).buffer]);

注意点

こちらの環境では上記の修正で特に問題は認められませんでしたが、環境によってはvar blob =のスクリプトへ{"type" : "text/csv"}を追加する必要があるかもしれません。

投稿2019/03/19 00:51

kisojin

総合スコア899

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

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

bossapporo

2019/03/19 03:22

一度base64にしてブラウザとの受け渡しをするのだと理解しました。 その手間を掛けずに、Shift_JISの文字列をそのまま渡せればいいような気がするのですが、そういうことはできないのでしょうか? とはいえ、希望することはこれで実現できました。ありがとうございます。
kisojin

2019/03/19 05:08 編集

ご返事ありがとうございます。解決したとのことで安心しました。Google Apps ScriptからHTML側へ値を渡す際には制限があるようで、bossapporoさんの方法では残念ながらblobを直接渡すことはできません。値を渡す際にutf8の文字列に変換されてしまうため、sjisの文字列を渡してもutf8に変換されてしまいます。また、blobを渡すと"blob"の文字列になってしまいます。(toString()が使われいているのかもしれません)このような状況と、掲載されているスクリプトを少し修正する方が理解しやすいかと思いましたのでいくつかある方法の一つとして上記のような回答を提案させていただきました。
guest

0

引数

object
** **オブジェクトの URL を生成するための File, Blob, MediaSource の何れかのオブジェクトです。
URL.createObjectURL - Web API | MDN

とのことですから、文字列→blob→文字列→blobのように何度も変換しなくても、普通にblobのまま渡せばいいように思いますが、それではダメなのでしょうか?

また、文字コード変換の目的がwindows環境のexcelで開くためであれば、BOMをつける、という方法もあるかと思います。
BOM付きUTF-8で文字化けしないCSV出力 | Railsの小技 | DoRuby

投稿2019/03/19 01:04

Lhankor_Mhy

総合スコア36057

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

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

bossapporo

2019/03/19 03:30

ご回答ありがとうございます。 ダウンロードしたファイルは別のWebサービスで利用するのですが、Shift_JISである必要があります。 ローカルでUTF-8からShift_JISに変換することも不可能ではないですが、後々の運用上、なるべく手間は省きたいと思っています。 普通にBlobのまま渡す方法ですが、getDataAsString()を付けないと、Blobの中身がまったくローカル側に転送されません。 もしよろしければ、具体的なコードをを提示していただけると助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問