スプレッドシートのグラフが.getBlob()でエラーになってしまう事象の回避策

GAS

さっきの記事で躓いたのですが、回避策を見つけました。

次の記事で、本来やりたかった家計簿のグラフをLINEに送るコードを載せます。

2021/12/29 追記
親切なコメントによりGoogleスライドを通さなくてもBlobが取得できることが分かりました。(ありがとうございます!)
コードもそのやり方でできるように変更しました。

追記ここまで

色々ググりましたが、結局V8エンジンで起きるバグなようです。
グラフを画像として保存するために素直にgetBlob()を使うのは、Googleさんが何とかするまでできないようです。

で、どうするかというと
一度Googleスライドにグラフだけコピーして、スライドから画像をGoogleドライブに保存する
という回りくどいやり方をするしかありませんでした。
参考サイト:https://tanaikech.github.io/2020/06/23/workaround-correctly-exporting-charts-on-google-spreadsheet-as-images-using-google-apps-script/

スプレッドシートからグラフをドライブに保存するコードを載せます。

function sendGraph() {
  const folderId = '****';  // Googleドライブの一時フォルダのID


  const sheet = getGraphSheet();
  const chart = sheet.getCharts()[0]; // グラフはシートにあるすべてが配列に取得される

  const today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'YYYY-MM-dd');
  const file_name = today + "_household_account.png"  
//  const slides = SlidesApp.create("temp");
//  const imageBlob = slides  // スライドに挿入した画像を変数に保存
//    .getSlides()[0]
//    .insertSheetsChartAsImage(chart)  // スライドにグラフを画像として挿入
//    .getAs("image/png");

  //2021-12-29 追記
  const chart = sheet.getCharts();
  const imageBlob = chart.getAs("image/png");
  // 追記ここまで

  const folder = DriveApp.getFolderById(folderId);  // 使用するドライブのフォルダーを指定
//  DriveApp.getFileById(slides.getId()).setTrashed(true);  // 
スライドは不要なのですぐ削除
  const file = folder.createFile(imageBlob.setName(file_name));  // 指定したフォルダーに画像を保存
  //DriveApp.getFolderById(folderId).removeFile(file)  // ドライブに保存した画像を削除
}

GASは便利!と思ってましたが、ちょっと深みに入るとまだまだバグがありますね。
1つのインフラ、1つの言語としてGoogleパワーに期待したいところです。

スポンサーリンク

コメント

  1. […] と思ったら、解決できました。こちらの記事をどうぞ […]

  2. 通りすがり より:

    getAsでできるようですよ

    const chart = graphsheet.getCharts()[0];
    const imageBlob = chart.getAs(‘image/png’);

    • たいぼん より:

      うわーできますね!
      ちょうど家計簿のGASをいじっていたところなので助かります。
      最初やろうとしたときにはできなかったと思うので、最近できるようになったんでしょうかね?

      情報ありがとうございます!

  3. たいぼん より:

    今月からなぜか下記がエラーになってしまうようになりました。
    Googleさん側のエラーかなあ
    const imageBlob = chart.getAs(“image/png”);

    急ごしらえですが、この記事の元々のやり方で回避可能です。
    for(let i in charts) {
    let chart = charts[i];

    let slides = SlidesApp.create(“temp”);
    let tmp_id = slides.getId();
    let imageBlob = slides // スライドに挿入した画像を変数に保存
    .getSlides()[0]
    .insertSheetsChartAsImage(chart) // スライドにグラフを画像として挿入
    .getAs(“image/png”);

    //let imageBlob = chart.getAs(“image/png”);
    let folder = DriveApp.getFolderById(folderId);
    let file = folder.createFile(imageBlob.setName(file_name));
    file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
    console.log(file.getDownloadUrl());
    pushImage(talkId, file.getDownloadUrl(),file.getDownloadUrl());
    file.setTrashed(true);

    //画像取得に使ったgoogleスライドを削除
    let tmpfile = DriveApp.getFileById(tmp_id);
    tmpfile.setTrashed(true);

    }

タイトルとURLをコピーしました