※現在このドキュメントは古い状態になっています。最新版は、こちらのサイトで改訂版を公開しています。
現在使用しているドキュメントやスプレッドシートをPDFに変換したいと思った時に、通常であればPDFプリンタやChromeの印刷機能などを利用して作成を行っていると思います。しかし、この場合、PDFファイルはデスクトップ等に出力され、そのPDFを流用したいと考えた場合、デスクトップからの添付やGoogle Driveにアップロードしてから利用するという手順を踏む必要性があります。ちょっとした手間なのですが、せっかく出力したものを、そのままの流れで流用するという要望は多いと思います。とりわけ、スクリプトを扱う上では、メールにそのまま添付して送付したいなどなど。
一度用意しておけば、他でも流用の効くテクニックだと思うのでここにメモをしておこうと思います。ちなみに、作成したスプレッドシートの様子は以下の通り。PDFアイコンにスクリプトを割り当てています。
function spreadsheet2pdfmail(){
//自分のIDと名前を取得する
var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var mysheetname = objSpreadsheet.getName();
//PDFに変換する(今回はルートディレクトリに作成)
var pdf = objSpreadsheet.getAs('application/pdf');
DocsList.createFile(pdf).rename(mysheetname);
//作成したPDFファイルをメールに添付して送る
var mail = 'test@gmail.com'
var subject = 'PDF送るよ'
var body = 'まぁ、送るんで見てくれ'
MailApp.sendEmail(mail, subject, body, {attachments:pdf});
}
今回のスクリプトは以下のポイントがあります。
特定のスプレッドシートをPDFに変換するためにはgetAsを使うことで可能でした。しかし、この方法はそのスプレッドシート全てがPDF化されてしまうので、正直ちょっと不便です。実際によく使う方法は、特定のシートをPDF化することでしょう。しかし、Google Appsには印刷に関するメソッドが存在しないので、エクスポートを利用してPDF化することが可能です。この方法は、PDF化だけじゃなく現在の特定のシートを別形式でエクスポートも可能なので、色々と使い勝手が良いメソッドです。
故に、PDF以外にもExcel形式やODS形式、CSV形式にも出来ます。スクリプトトリガーなどと合わせることで、自動的にデータを集めて、自動的にPDF化して、解析したページだけメールに添付して送るなんて芸当もこれで可能になります。
function sheet2pdf2mail() {
//アクティブシートのIDとGIDを取得する
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetID = sheet.getSheetId();
var key = ss.getId();
//作成するPDFのファイル名
var name = "testman.pdf";
//PDF生成するURLをfetchする
var pdf = UrlFetchApp.fetch("https://docs.google.com/a/spreadsheets/d/"+key+"&gid="+sheetID+
"&format=pdf&portrait=false&size=A4&gridlines=false&fitw=true")
.getBlob().setName(name);
//作成したPDFファイルをメールに添付して送る
var mail = '送信先メールアドレスをここに入れる'
var subject = 'PDF送るよ'
var body = 'まぁ、送るんで見てくれ'
MailApp.sendEmail(mail, subject, body, {attachments:pdf});
}
URLに続けてオプションを付加すると、Chromeでの印刷時と同じオプションを付け加えることが出来る。重要度の高い物を赤字、次に必要な物を青字で説明してみた。
図:OAuth関係!?のちょっと特殊な承認画面
//masterシートをPDF化してドライブに保存、mailで送信する関数
function sheet2pdf2mail() {
//PDF化して送信する確認ダイアログ
var ui = SpreadsheetApp.getUi();
var re = ui.alert("PDF化して送信", "masterシートをPDF化してメール送信しますか?", ui.ButtonSet.YES_NO_CANCEL);
switch(re){
case ui.Button.YES:
break;
case ui.Button.NO:
ui.alert("送信を中止しました。");
return 0;
break;
case ui.Button.CANCEL:
ui.alert("送信をキャンセルしました。");
return 0;
break;
}
//現在のシートのIDとGIDを取得する
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("master");
var filterday = sheet.getRange("D1").getValue();
var sheetID = sheet.getSheetId();
var key = ss.getId();
//作成するPDFのファイル名
var name = "作成書類" + getDate(filterday) + ".pdf";
//OAuthのセッティング
var oauthConfig = UrlFetchApp.addOAuthService("spreadsheets");
var scope = "https://docs.google.com/feeds"
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://accounts.google.com/OAuthAuthorizeToken");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
var Params = {
oAuthServiceName: 'spreadsheets',
oAuthUseToken: 'always',
};
//PDF出力をするURLをFetchする
var pdf = UrlFetchApp.fetch('https://docs.google.com/a/ドメイン名/spreadsheets/d/'+key+'/export?gid='+sheetID+
'&format=pdf&portrait=false&size=A4&gridlines=false&fitw=true',Params)
.getBlob().setName(name);
//作成したPDFをフォルダに格納する
var folder = DocsList.getFolderById("ここにPDF作成先フォルダのIDを入れる");
var file = folder.createFile(pdf);
var fileid = file.getId();
var milkysky = "https://docs.google.com/a/ドメイン名/file/d/" + fileid;
//送信先を取得する
var sendlist = SpreadsheetApp.openById("送信先リストであるスプレッドシートのIDを指定"); //mailsendlistを直接指定
var todatabase = sendlist.getSheetByName("tolist").getRange("A2:H").getValues();
var mail = "";
for(var i = 0;i < todatabase.length;i++){
if(todatabase[i][0] == "作成書類"){
//項目名がヒットしたら、ccデータがあるやつを全て変数に含める。
for(var j = 1;j < 7;j++){
if(todatabase[i][j] == ""){
}else{
mail = mail + todatabase[i][j] + ",";
}
}
}else{
}
}
//CC送信先を取得する
var ccdatabase = sendlist.getSheetByName("ccdatabase").getRange("A2:G").getValues();
var cc = "";
for(var i = 0;i < ccdatabase.length;i++){
if(ccdatabase[i][0] == "○○事務所"){
//施設名がヒットしたら、ccデータがあるやつを全て変数に含める。
for(var j = 1;j < 6;j++){
if(ccdatabase[i][j] == ""){
}else{
cc = cc + ccdatabase[i][j] + ",";
}
}
}else{
}
}
//送信者をCCに加える
cc = cc + GetUser();
//body文章を作成する。
//改行するには <br>や<p> を入れてください
・・・・省略・・・・
var body =""; //本文
body += header;
body += bodytop;
body += footer;
//作成したPDFファイルをメールに添付して送る
var subject = "作成書類" + getDate(filterday) + "分";
var titlename = "テスト送信";
MailApp.sendEmail({
to: mail,
subject: subject,
htmlBody: body,
cc: cc,
name:titlename,
});
}
データの書き込みを行い、其の流れでPDFを生成する場合にいは、データの書き込みが間に合わずPDFが生成されてしまうケースが、しばしばあります。
このままでは、折角のPDFもデータが欠けた状態で作成されてしまうので、以下のような無限ループを利用して、「最終書き込みセル」を確認しながら、スクリプトをウェイトさせます。
//最終rangeに書き込みがされていない場合、無限ループ
var rangechk = SpreadsheetApp.openById(filesId).getRange("comments").getValue();
while (rangechk == ""){
rangechk = SpreadsheetApp.openById(filesId).getRange("comments").getValue();
}
最終書き込みをするであろう場所を今回は、名前付き範囲で指定しています。
その中身が空の状態の時は無限ループします。値が確認できたら、PDF生成ルーチンへ進むといった感じです。