2024年5月31日

GASを使ってローカルPCの日本語テキストファイルをアップロードし英語に変換してみた。

 

亀老山山頂から望む来島海峡
亀老山山頂から望む来島海峡 


Google Apps Script(以下,GASという)を使う機会を得たので,ついでにローカルパソコン(以下PCという)のテキストファイルについて,GASではどのような扱いになるか学習することにしました。

今回は,PCにあるローカルテキストファイルをアップロードして,加工・蓄積するGASスクリプトになります。

仕事でPCを使う企業は,セキュリティ上,社内に情報を閉じ込める事が多く,そのためPC常駐ソフトであるマイクロソフトエクセルのVBAや自主開発ソフトを使う事が多くなります。

しかし,それではクラウドなどの外部サービスを使えないため発展性に乏しく,生産性や競争力が見劣りすることになり,外部のサービスをどのように活用して行くかが今後の課題です。

そのような中,Google Apps Script(GAS)は時間制限や処理回数制限があり,クラウド特有の使いづらいさはありますが,小規模な事務作業の効率化やデータバックアップ,外部WebAPIへの応用などで利用価値があると考えます。

この主旨に則り,ローカルPCにある日本語テキストファイルをブラウザ機能を使って,GoogleドライブのGASスクリプトにアップロードし,英語に翻訳後スプレッドシートに出力してみました。

GASスクリプトに入ってしまえば,アップロードファイルをドキュメント変換することも容易ですが,GASには,エクセルVBAのようなテキストファイルを直接読み書きする関数がないため,ファイルを全て配列に読み込んで加工後出力します。

今回は,スクリプトの処理結果を早く見たかったので,この出力部分をスプレッドシートにしています。

テキストの翻訳なんて,今ではあまり珍しくありませんが,GASの関数で行えるのにはちょっと驚きました。

それでは,学習を開始します。



 


  今回のGASスクリプトのあらまし


今回作成するスクリプトの外観図は以下のようになります。

GASアップロード外観図
GASアップロード外観図


作成を簡易化するため,今回はGoogleドライブスプレッドシートからのボタン起動にしています。

そのため,GASスクリプトの起動function関数に「doGetやdoPost」は使っていません。ブラウザ画面から起動したい方は,起動functionを変更する必要があります。

また,GASスクリプトでアップロードファイルの選択が必要になりますので,HTMLが利用できる「モーダルダイアログ」を利用しています。

一般ブラウザの「モーダルウィンドウ」は非推奨になったようなので,こちらもいつまで使えるかはわかりません。

ファイルのアップロードは,HTMLとjavascriptによりファイル選択とGASへのファイル受け渡しを行っています。

これにより,「モーダルダイアログ」からGASスクリプトへファイルをアップロードすることが可能です。

あとは,アップロードされたテキスト文を一行ずつ日本語から英文に翻訳して,スプレッドシートに書き込んでいるだけです。

受け取り側でテキストにさえ出来れば,音声にだって変換することが可能です。

因みに今回はテキスト文のみに限定していますが,画像などのバイナリーアップロードについても後日やってみたいと思います。

また,ファイルの読込にはHTML5のFILEAPIを利用していますが,「reader.onload」などのイベントハンドラーは極力利用せず,javascript標準である「addEventListener」などのイベントハンドラーを用いてコーディングしています。




  モーダルダイアログの出力

それでは,早速,GASコードの作成に入っていきます。

GASコードは,Googleスプレッドシートの拡張機能タグの中にあるApps ScriptからGASコードエディターを開き,左側にある「コード.gas」を編集します。

今回は,「main.gs」に名前を変更し,function名も「main」に変更しました。

「モーダルダイアログ」表示用コーディングは次のようになります。

main.gs

function main() {
  var html = HtmlService.createHtmlOutputFromFile("index");
  SpreadsheetApp.getUi().showModalDialog(html, 'ローカルファイル読込');
}

ここでは,GASで新たに作成した「index.html」というHTML文のオブジェクトを取得し,そのオブジェクトをGoogleスプレッドシートAppクラスのUiオブジェクト下にあるモーダルダイアログメソッドに渡しています。

モーダルダイアログの画面サイズは,「createHtmlOutputFromFile("index")」に続けて「.setWidth(500).setHeight(300);」等と打てば調整できます。

これにより,スプレッドシート上にHTMLを処理できるモーダルダイアログが表示されます。

なお,起動時のfunction名は「main」としました。




  モーダルダイアログHTMLの作成


続いて,モーダルダイアログ用の「index.html」の作成に入ります。これは,Apps Scriptコードエディター画面の左側上部にあるファイル「+」ボタンを押して作成します。

具体的なコーディングは以下のとおりです。


index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    </base>
  </head>
  <body>
    <form id="myForm" enctype="multipart/form-data">
      <input id="File_in" name="myFile" type="file" multiple><p></p>
      <button id="Click" type="file">読込</button>
    </form>
    <hr />
    <pre id="result"></pre>
  </body>
  <script>
    // フォームの読込クリックで呼ばれる処理
    window.addEventListener('DOMContentLoaded', function() {
      document.getElementById("Click").addEventListener('click', function(e){
        //選択されたファイルを取得(単一なので[0]に決め打ち
        var fileObject = document.getElementById('File_in').files[0];
        //ファイルが選択されているかチェックする
        if ((typeof fileObject) === 'undefined'){
          alert('ファイルが選択されていません');
          return;
        }        
        // テキストファイルを判定
        if (!fileObject.type.match('text.*')) {
          alert("テキストファイル以外は転送できません。");
          return;
        }
                
        //FileReaderオブジェクトを生成する
        var reader = new FileReader();
        
        //読込成功時の処理
        reader.addEventListener('load', function(){
          document.getElementById('result').textContent = reader.result;
          
          // GASで定義した関数を呼び出す
          google.script.run
          .withFailureHandler(function(err) {
           alert("\n\n" + err.message + "\n\nファイル名:" + fileObject.name);
           spread_syuryo();
          }).withSuccessHandler(function() {
           //処理が完了したので画面を閉じる"
           spread_syuryo();
          }).writeSheet(reader.result, fileObject.name, fileObject.type);        
        
        },true);
        
        //読込失敗時の処理
        reader.addEventListener('error', function(){
          alert("FILEAPI読込エラー = " + reader.error.message);
        },true);
        
        //アップロードファイルをrederに読み込む
        reader.readAsText(fileObject,"UTF-8");
      },true); 
    });
    //終了処理
    function spread_syuryo(){
      // スプレッドシートで、アップロードUIを自動的に閉じる
      google.script.host.close();
    }
  </script>
</html>

formタグで,ファイルの選択を行っています。「ファイル選択」ボタンと「読込」ボタンを表示させるため,Inputタグとbuttonタグを利用しています。

enctypeは,複数ファイルを扱えるよう「multipart/form-data」としています。また,ファイル読込内容をダイアログに表示するため,preタグを利用して「result」というidを定義しています。

続いて,JavaScriptのコードを記述します。イベントドリブンによる記述となるため,最初にページが開いた時に起動するよう,「window.addEventListener('DOMContentLoaded', function(){ページ内の記述});」を記述をしています。

次に,ページ内の記述を書いていきます。動作のきっかけとして,「ファイル選択」の後「確認」ボタンを押した段階で,読み込んだファイルのオブジェクトを取得するようにします。

そのため,最初にHTMLの「button」タグがクリックされた段階で処理を行いたいので,そのidを「id="Click"」として,javascriptに 「document.getElementById("Click").addEventListener('click', function(e){この中に処理を書く},true};」と書きます。

あとは,このfunction関数内にクリックされた時の処理を書けばいいのですが,今回は,テキストファイルを一つだけを読むことにしています。

ファイルオブジェクトは,「document.getElementById('File_in').files[0];」で取得します。

「Click」した段階で,ファイルの選択をしていないことも考えられますので,ファイルオブジェクトが存在することを確認するため,「typeof」演算子を使ってファイルが選択されていることや,matchメソッドを使って「Text」ファイルであることを確認しています。

続いて,ファイルの読込はFILEAPIを使いますので,FileReaderオブジェクトを生成します。

ファイル読込成功を切っ掛けに発火させるよう,「reader.addEventListener('load', function(){この中に処理を書く},true);」と書きます。

この中の処理として,「google.script.run.withFailureHandler(function(err) {エラー処理}).withSuccessHandler(function() {正常処理}).writeSheet(reader.result, fileObject.name, fileObject.type);」と記述し,GASの「writeSheet()」関数に必要なデータを引数として渡しています。

また,この発火処理の後に,「reader.readAsText(fileObject,"UTF-8");」として,filereaderにテキストファイルを読み込んでいます。

この読込が失敗した時の処理として,「reader.addEventListener('error', function(){エラー 処理},true);」も加えています。

後は,終了処理functionとして,「google.script.host.close();」を作成しています。これをコールすればGASの処理が終了します。



  GAS側ファイル受信処理


先ほど,ファイル読込によって発火した際,「google.script.run」を使って,GASスクリプトの「writeSheet」という関数を起動しました。

その際,引数に「データ, ファイル名,オブジェクト型」を渡して,処理を行っています。

具体的なコードは以下のとおりです。「function writeSheet()」以降を追記しています。


main.gs

function main() {
  var html = HtmlService.createHtmlOutputFromFile("index");
  SpreadsheetApp.getUi().showModalDialog(html, 'ローカルファイル読込');
}
function writeSheet(data, fileName, mimeType) {

  // HTMLから受け取ったdataからデータ交換用blobオブジェクトを取得する
  const blob = Utilities.newBlob(data,mimeType,fileName);
  console.log(blob.getDataAsString());
  
  // テキストとして取得(Windowsの場合、文字コードに Shift_JIS を指定)
  var text = blob.getDataAsString("UTF-8");  
  
  // 改行コードで分割し配列に格納する
  var textLines = text.split(/\n|\r\n|\r/g);

  // 加工先配列を定義する
  var targetLines = new Array(textLines.length);

  // 取得したテキストから加工先配列に翻訳関数で処理する
  for(i = 0; i < textLines.length; i++){
    targetLines[i] = LanguageApp.translate(textLines[i], 'ja', 'en');
  }

  // 書き込むシートクラスを取得
  var sheet = SpreadsheetApp.getActiveSheet();

  // テキスト配列をシートに展開する
  for (i = 0; i < textLines.length; i++) {
    sheet.getRange(i + 2, 1).setValue(textLines[i]);
    sheet.getRange(i + 2, 3).setValue(targetLines[i]);
  }
  
  // 処理終了のメッセージボックスを出力
  Browser.msgBox("ローカルファイルを読み込みました");
}

簡単に説明します。

「index.html」から渡されたデータを 「Utilities.newBlob(data,mimeType,fileName);」で一応Blobファイルに変換します。Blobファイルとは,ファイルデータ交換用のオブジェクトのことで,バイナリ・ラージ・オブジェクトの略です。

このblobファイルを「 blob.getDataAsString("UTF-8");」で文字列に変換します。

この文字列を,splitメソッドを使って行ごとの文字配列に変換して,各々の配列を「LanguageApp.translate(文字列, 'ja', 'en')」関数を使って,日本語を英語に変換しています。

変換した文字列を,スプレッドシートのクラスを取得して,任意のセルに出力します。

最後に,Browser.msgBox(メッセージ文字列)で終了メッセージを出力しました。



  4.最後に

最終的に,入力したテキスト文例は以下の内容です。

【テキストファイル】

ようこそ,GASへ。
Google Apps Scriptは、Googleによって開発されたスクリプト言語です。
 小規模なアプリケーション開発のためのプラットフォームになります。
 主に事務処理などを自動化するために用いられます。
 新しい世界をご覧下さい。


出力したスプレッドシートの内容は以下のとおりです。

【スプレッドシートの内容】

スプレッドシートの出力図例
スプレッドシートの出力図



左側が日本語,右側が英語になっています。GASの実行を用意にするために,右側に実行ボタンをつけています。

GAS(main)の「実行ボタン」への割り当ては,図形で「実行ボタン」を作って右クリックで図形を選択後,左クリックすると「スクリプトを割り当て」欄が表示されます。

今回の学習デモは,予め上記のようなスプレッドシートを準備して,コンバインドスクリプトの形で作りました。

javascriptに精通しておられる方々には簡単でしょうが,実証を得るのに結構時間がかかりました。

javascriptのイベントドリブン型記述はいろいろな表記方法があり,今回お示しした内容だけではありません。いろいろとトライ&エラーをしないと分からない点が多いと感じたところです。

それでは,楽しいITリテラシーライフをお過ごしください。


(ご注意)情報の正確性を期していますが,実施される場合には自己責任でお願いします。

0 件のコメント: