Google应用脚本getAs('application / pdf')布局

时间:2017-07-20 08:39:55

标签: pdf printing google-apps-script

我使用我找到的here应用脚本从电子表格生成PDF文件。  这个用旧的  方法getAs('application / pdf')并且效果很好。

问题是以这种方式生成的PDF文档具有不需要的非对称边距(右侧较大,左侧较窄)。我只是希望页面居中。奇怪的是,当我从谷歌菜单打印文件 - >打印(或Ctrl + P)文档显示正确居中。

我的代码如下所示:

function CreaPDF() {
  //The function prints an invoice to PDF. First it copies spreadsheet to a new document.
  //Deletes all sheet except the one to print. Saves it to PDF. 
  //It overwrites any existing doc with same name.

  var sourceSpreadsheet = SpreadsheetApp.getActive();          
  var sheetName = "Factura";
  var folderID = getParentFolder(); // Folder id to save in a folder.
  var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
  var folder = DriveApp.getFolderById(folderID); 
  var numf = sourceSpreadsheet.getRangeByName("NumeroFactura").getValue();
  var anof = numf.split("/",2);   // Seeks number and year -> filename 

  var pdfName = anof[1] +"_Factura_" + anof[0]+ "_Dra_Salazar"; // Nombre del documento;

  //Copy whole spreadsheet 2 temporary sheet
  var destSpreadsheet = SpreadsheetApp.open(DriveApp.getFileById(sourceSpreadsheet.getId()).makeCopy("tmp_convert_to_pdf", folder))

  //delete redundant sheets
  var sheets = destSpreadsheet.getSheets();
  for (i = 0; i < sheets.length; i++) {
    if (sheets[i].getSheetName() != sheetName){
    destSpreadsheet.deleteSheet(sheets[i]);
    }
  }

  //Deletes pdf if already exists
  var files = DriveApp.getFilesByName(pdfName);
  while (files.hasNext()) {
   files.next().setTrashed(true);
   }
  var destSheet = destSpreadsheet.getSheets()[0];
  //repace cell values with text (to avoid broken references)
  var sourceRange = sourceSheet.getRange(1, 1,sourceSheet.getMaxRows(),sourceSheet.getMaxColumns());

  var sourcevalues = sourceRange.getDisplayValues();
  var destRange = destSheet.getRange(1, 1, destSheet.getMaxRows(), destSheet.getMaxColumns());
  destRange.setValues(sourcevalues);

  SpreadsheetApp.getActiveSpreadsheet().toast('Creando PDF');

  //save to pdf
  var theBlob = destSpreadsheet.getBlob().getAs('application/pdf').setName(pdfName);
  var newFile = folder.createFile(theBlob);

  //Delete the temporary sheet
  DriveApp.getFileById(destSpreadsheet.getId()).setTrashed(true);
  return true;
}

我打印时的设置是:

  • 纸张尺寸:“A4”
  • 比例:“正常”(我也试过:“适合宽度”和 “适合页面”)
  • 方向:“肖像”
  • 边距:“正常”

正如Google Help Forums中所见,谷歌打印的方式似乎是个老问题。总之,似乎没有保存打印设置,也没有办法将任何参数传递给getAs('application / pdf')方法。所以我假设方法(和菜单打印选项)使用无法修改的默认参数。对此有何解决方案? “打印或更改页面设置”帮助页面没有太大帮助。

非常感谢

3 个答案:

答案 0 :(得分:2)

根据https://ctrlq.org/code/19869-email-google-spreadsheets-pdf

尝试此解决方案

使用export url参数,您可以为result pdf设置所需的选项。您还可以设置要导出的工作表的特定ID,因此您不需要复制整个电子表格。

function CreaPDF() {
  //The function prints an invoice to PDF. First it copies spreadsheet to a new document.
  //Deletes all sheet except the one to print. Saves it to PDF. 
  //It overwrites any existing doc with same name.

  var sourceSpreadsheet = SpreadsheetApp.getActive();          
  var sheetName = "Factura";
  var folderID = getParentFolder(); // Folder id to save in a folder.
  var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
  var folder = DriveApp.getFolderById(folderID); 
  var numf = sourceSpreadsheet.getRangeByName("NumeroFactura").getValue();
  var anof = numf.split("/",2);   // Seeks number and year -> filename 

  var pdfName = anof[1] +"_Factura_" + anof[0]+ "_Dra_Salazar"; // Nombre del documento;

  SpreadsheetApp.getActiveSpreadsheet().toast('Creando PDF');

  // export url
  var url = 'https://docs.google.com/spreadsheets/d/'+sourceSpreadsheet.getId()+'/export?exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
  + '&size=A4'                           // paper size legal / letter / A4
  + '&portrait=true'                     // orientation, false for landscape
  + '&fitw=false'                        // fit to page width, false for actual size
  + '&sheetnames=false&printtitle=false' // hide optional headers and footers
  + '&pagenumbers=false&gridlines=false' // hide page numbers and gridlines
  + '&fzr=false'                         // do not repeat row headers (frozen rows) on each page
  + '&gid='+sourceSheet.getSheetId();    // the sheet's Id

  var token = ScriptApp.getOAuthToken();

  // request export url
  var response = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' +  token
    }
  });

  var theBlob = response.getBlob().setName(pdfName+'.pdf');

  // delete pdf if already exists
  var files = folder.getFilesByName(pdfName);
  while (files.hasNext())
  {
    files.next().setTrashed(true);
  }

  // create pdf
  var newFile = folder.createFile(theBlob);

  return true;
}

答案 1 :(得分:0)

在Kos提供的解决方案之前,我终于设法通过播放单元格的尺寸来调整我的纸张尺寸,使其显得“#34;居中”#34;但无论如何,非常感谢科斯。你的答案肯定解决了这个问题。太好了!

答案 2 :(得分:0)

出于科斯的灵魂动机

我跟踪了由Google电子表格Download as GUI与chrome开发人员工具创建的请求。当您点击next中的Print settings时,chrome发送请求并获取pdf文件。

开始追逐吧。下面是我的代码。

var sourceSpreadsheet = SpreadsheetApp.getActive();
var url = 'https://docs.google.com/spreadsheets/d/' + sourceSpreadsheet.getId() + '/pdf?id=' + sourceSpreadsheet.getId()
var formData = {
    'a': 'false',
    'pc': '[null,null,null, ... SOME VERY LONG LIST OF NULLS AND NUMBERS ... 166]],[[0,5]]]],0]',
    'gf': '[]'
};
var token = ScriptApp.getOAuthToken(); // doesn't needed when sheet is public
var options = {
        'method': 'post',
        'payload': formData,
        'muteHttpExceptions': true,
        headers: {
            'Authorization': 'Bearer ' + token
        }
    };
var response = UrlFetchApp.fetch(url, options)

var theBlob = response.getBlob().setName('YourPDFName.pdf');

您可以按照以下步骤填写formData['pc']
1.在Network标签上记录请求。
2.单击pdf?id=blahblah pic for step 2
3.向下滚动以找到Form Data pic for step 3
4.复制表格数据并填写代码。

表单数据如下:
[null,null,null,null,null,null,null,null,null,0,[["$Sheet_id"]],10000000,null,null,null,null,null,null,null,null,null,null,null,null,null,null,$day_after_30-12-1899,null,null,[$note,null,1,$note,0,0,0,0,$fixed_row,1,1,1,$headers,$footers,1,1],["A4",1,2,1,[0.75,0.75,0.7,0.7]],null,0,[["$Sheet_id",[[26,52]....],[[0,5]]]],0]
还有更多参数,但我找不到它们全部。同样,参数也可能是错误的,因为我通过检查更改的值发现了它们的值。

更改$ day_after_30-12-1899时,以pdf格式打印的日期会更改。

您可以自定义页眉/页脚。它们是UTF16编码的,并且具有多个控制字符。

| Name in `Download as` GUI | character | 
|---------------------------|-----------|
| page number A             | \uee12    |
| page number B             | \uee15    |
| page number C             | \uee16    |
| Workbook title            | \uee10    |
| sheet name                | \uee11    |


|   meaning in date & time  | character | 
|---------------------------|-----------|
| date formatstr start      | \uee13    |
| year                      | yyyy      |
| month                     | M         |
| day                       | d         |
| date formatstr end        | \uee14    |
|                           |           |
| time formatstr start      | \uee17    |
| am or pm                  | am/pm     |
| hour in 12hour clock      | h         |
| minute                    | mm        |

您可以使用YourText\uee13yy. M. d\uee14Yourtext

这样的时间和日期

我建议使用GUI创建formData['pc']并修改$day_after_30-12-1899

*欢迎进行任何更正。虽然我不是英语母语人士,但有很多尴尬/错误的表达方式。