我正在尝试制作一个谷歌脚本,用于将新版本的谷歌电子表格(或表格)导出(或打印)为pdf,页面参数(纵向/横向,...)
我对此进行了研究,并找到了可能的解决方案here。 有几个类似的解决方案,但只适用于旧版本的谷歌电子表格。
请考虑以下代码:
function exportAsPDF() {
//This code runs from a NEW version of spreadsheet
var oauthConfig = UrlFetchApp.addOAuthService("google");
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://spreadsheets.google.com/feeds/");
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous"); oauthConfig.setConsumerSecret("anonymous");
var requestData = { "method": "GET", "oAuthServiceName": "google","oAuthUseToken": "always" };
var ssID1="0AhKhywpH-YlQdDhXZFNCRFROZ3NqWkhBWHhYTVhtQnc"; //ID of an Old version of spreadsheet
var ssID2="10xZX9Yz95AUAPu92BkBTtO0fhVk9dz5LxUmJQsJ7yPM"; //ID of a NEW version of spreadsheet
var ss1 = SpreadsheetApp.openById(ssID1); //Old version ss object
var ss2 = SpreadsheetApp.openById(ssID2); //New version ss object
var sID1=ss1.getActiveSheet().getSheetId().toString(); // old version sheet id
var sID2=ss2.getActiveSheet().getSheetId().toString(); // new version sheet id
//For Old version, this runs ok.
var url1 = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="+ssID1+"&gid="+sID1+"&portrait=true"+"&exportFormat=pdf";
var result1 = UrlFetchApp.fetch(url1 , requestData);
var contents1=result1.getBlob();
var pdfFile1=DriveApp.createFile(contents1).setName("FILE1.pdf");
//////////////////////////////////////////////
var url2 = "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key="+ssID2+"&gid="+sID2+"&portrait=true"+"&exportFormat=pdf";
var result2 = UrlFetchApp.fetch(url2 , requestData);
var contents2=result2.getBlob();
var pdfFile2=DriveApp.createFile(contents2).setName("FILE2.pdf");
}
它正常工作并生成文件“FILE1.pdf”,可以正确打开。但是对于新版本的电子表格,它会在“ var result2 = UrlFetchApp.fetch(url2,requestData); ”中导致错误302(截断的服务器响应)。好吧,没关系,因为新版本的url格式不包含“key”参数。新版本的正确网址必须与 "https://docs.google.com/spreadsheets/d/"+ssID2+"/export?gid="+sID2+"&portrait=true&format=pdf"
将此用于url2( var url2 = "https://docs.google.com/spreadsheets/d/"+ssID2+"/export?gid="+sID2+"&portrait=true&format=pdf"
),它再次失败并显示错误“无法为服务执行授权:google ”。
好吧,这个错误可能是由于 RequestTokenUrl 的范围不正确造成的。我找到了替代范围https://docs.google.com/feeds
并设置了它:oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope=https://docs.google.com/feed/");
代码再次运行后,UrlFetchApp.fetch(url2 , requestData);
行发生了新的错误:“错误OAuth ”...我不知道如何继续...我已经测试了数百种变化而没有好处结果
有什么想法吗?对于新版电子表格, docs.google.com/feeds 的范围是否正确?是否正确 oauthConfig ?
提前致谢。
答案 0 :(得分:8)
这是我的电子表格到pdf脚本。它适用于新的Google Spreadsheet API。
// Convert spreadsheet to PDF file.
function spreadsheetToPDF(id,index,url,name)
{
SpreadsheetApp.flush();
//define usefull vars
var oauthConfig = UrlFetchApp.addOAuthService("google");
var scope = "https://docs.google.com/feeds/";
//make OAuth connection
oauthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oauthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oauthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oauthConfig.setConsumerKey("anonymous");
oauthConfig.setConsumerSecret("anonymous");
//get request
var request = {
"method": "GET",
"oAuthServiceName": "google",
"oAuthUseToken": "always",
"muteHttpExceptions": true
};
//define the params URL to fetch
var params = '?gid='+index+'&fitw=true&exportFormat=pdf&format=pdf&size=A4&portrait=true&sheetnames=false&printtitle=false&gridlines=false';
//fetching file url
var blob = UrlFetchApp.fetch("https://docs.google.com/a/"+url+"/spreadsheets/d/"+id+"/export"+params, request);
blob = blob.getBlob().setName(name);
//return file
return blob;
}
我必须使用“muteHttpExceptions”参数来确切地知道新的URL。使用此参数,我使用HTML扩展程序下载了我的文件以获取“永久移动”页面,其中包含我的最终网址(“https://docs.google.com/a/”+ url +“/ spreadsheets / d /”+ id +“/ export”+ params“ )。
请注意我在一个组织中。所以我必须指定其域名(“url”参数,即“mydomain.com”)。
答案 1 :(得分:4)
(从this answer复制。)
此功能是对“ianshedd ...”here提供的脚本的改编。
有:
oAuthConfig
。通过一些研究和努力,您可以连接到在线PDF Merge API,以生成单个PDF文件。除此之外,直到谷歌提供了一种方法来导出一个PDF中的所有工作表,你就会遇到单独的文件。
脚本:
/**
* Export one or all sheets in a spreadsheet as PDF files on user's Google Drive,
* in same folder that contained original spreadsheet.
*
* Adapted from https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579#c25
*
* @param {String} optSSId (optional) ID of spreadsheet to export.
* If not provided, script assumes it is
* sheet-bound and opens the active spreadsheet.
* @param {String} optSheetId (optional) ID of single sheet to export.
* If not provided, all sheets will export.
*/
function savePDFs( optSSId, optSheetId ) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
// Get URL of spreadsheet, and remove the trailing 'edit'
var url = ss.getUrl().replace(/edit$/,'');
// Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
// Get array of all sheets in spreadsheet
var sheets = ss.getSheets();
// Loop through all sheets, generating PDF files.
for (var i=0; i<sheets.length; i++) {
var sheet = sheets[i];
// If provided a optSheetId, only save it.
if (optSheetId && optSheetId !== sheet.getSheetId()) continue;
//additional parameters for exporting the sheet as a pdf
var url_ext = 'export?exportFormat=pdf&format=pdf' //export as pdf
+ '&gid=' + sheet.getSheetId() //the sheet's Id
// following parameters are optional...
+ '&size=letter' // paper size
+ '&portrait=true' // orientation, false for landscape
+ '&fitw=true' // fit to width, false for actual size
+ '&sheetnames=false&printtitle=false&pagenumbers=false' //hide optional headers and footers
+ '&gridlines=false' // hide gridlines
+ '&fzr=false'; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
var response = UrlFetchApp.fetch(url + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + ' - ' + sheet.getName() + '.pdf');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
}
答案 2 :(得分:0)
谢谢!
变体2与我配合使用:
var requestData = {
"oAuthServiceName": "spreadsheets",
"oAuthUseToken": "always" };
然后:
var ssID = ss.getId()
var sID = ss.getSheetByName(name).getSheetId()
//creating pdf
var pdf = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/"+ssID+"/export?gid="+sID+"&portrait=false&size=A4&format=pdf", requestData).getBlob();
//folder to created pdf in
var folder = DriveApp.getFolderById(id)
//creating pdf in this folder with given name
folder.createFile(pdf).setName(name)
我可以使用列出的参数完美地更改图像大小,方向等。