0

I want to have a script/ print button that, after i print the page, it will change the sheet color from red to green/ or else.

Because, my team create many bills, but we don't know which bill is printed to send. Is there any way to know which bills is printed out.

Tân
  • 1
  • 15
  • 56
  • 102

1 Answers1

1

Implementing custom printing functions for Google Sheets is quite a tricky topic. There is no way of setting a trigger to run when the print function is executed.

Adapted from this Stackoverflow answer on how to print a Range in a Sheet, you could implement the code below:

var PRINT_OPTIONS = {
  'size': 7,               // paper size. 0=letter, 1=tabloid, 2=Legal, 3=statement, 4=executive, 5=folio, 6=A3, 7=A4, 8=A5, 9=B4, 10=B
  'fzr': false,            // repeat row headers
  'portrait': true,        // false=landscape
  'fitw': true,            // fit window or actual size
  'gridlines': false,      // show gridlines
  'printtitle': false,
  'sheetnames': false,
  'pagenum': 'UNDEFINED',  // CENTER = show page numbers / UNDEFINED = do not show
  'attachment': false
}

var PDF_OPTS = objectToQueryString(PRINT_OPTIONS);

function onOpen(e) {
  SpreadsheetApp.getUi().createMenu('Print...').addItem('Print sheet', 'printSheet').addToUi();
}

function printSheet() {
  SpreadsheetApp.flush();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var range = sheet.getDataRange();

  var gid = sheet.getSheetId();
  var printRange = objectToQueryString({
    'c1': range.getColumn() - 1,
    'r1': range.getRow() - 1,
    'c2': range.getColumn() + range.getWidth() - 1,
    'r2': range.getRow() + range.getHeight() - 1
  });
  var url = ss.getUrl().replace(/edit$/, '') + 'export?format=pdf' + PDF_OPTS + printRange + "&gid=" + gid;

  var htmlTemplate = HtmlService.createTemplateFromFile('js');
  htmlTemplate.url = url;
  SpreadsheetApp.getUi().showModalDialog(htmlTemplate.evaluate().setHeight(10).setWidth(100), 'Print range');

  sheet.setTabColor("ff0000"); // change tab color to red after sheet has been printed
}

function objectToQueryString(obj) {
  return Object.keys(obj).map(function(key) {
    return Utilities.formatString('&%s=%s', key, obj[key]);
  }).join('');
}

You will also need to create an HTML file in your project. You can do that by clicking on File>New>HTML File within the editor, setting its name to js, and pasting the following content into it:

<script>
  window.open('<?=url?>', '_blank', 'width=800, height=600');
  google.script.host.close();
</script>

All this together will create a menu item on top of your Sheets UI, that when you click on it, will bring you to a PDF-export of your Sheet from which you will be able to print your Sheet. Furthermore, it will set the tab color to red, to represent that the Sheet has already been printed.

carlesgg97
  • 4,184
  • 1
  • 8
  • 24
  • Great Thanks to @carlesgg97, I'll try it out and see. I'm amazed about how fast and thoughtfull your respond is. Thank you! – Nguyen Thi Lan Anh Nov 28 '19 at 10:22
  • I did try it, but it said about : function printSheet() is: ReferenceError: "PDF_OPTS" undefined. How can i fix it?. Thank you – Nguyen Thi Lan Anh Nov 28 '19 at 11:20
  • @NguyenThiLanAnh Did you copy the entire code? notice that `PDF_OPTS` is a variable defined in the global scope. That definition should be present in your code too. If this till does not work, kindly move that variable definition inside the `printSheet()` function, in the first line of it. – carlesgg97 Nov 28 '19 at 11:53
  • Thanks @Carlesgg97, I'll try it, when i click the button, it show a litter box: Print Range and open a new window said: Sorry, can not open the file at the moment and show non pdf or print any thing. Did i do any thing wrong? – Nguyen Thi Lan Anh Nov 29 '19 at 04:26
  • I did copy the whole code, and the range i want to prin is: i1 to N. What changes i have to make? Thank you so much! – Nguyen Thi Lan Anh Nov 29 '19 at 04:29
  • @NguyenThiLanAnh Kindly try copying and pasting the code again (I've done a couple small fixes). Afterwards, when opening the Sheet you'll have to click, on the upper menu, `Print...>Print sheet`. At that time, you will have to accept an incoming pop-up request on your browser. That will make it possible to open a PDF file where you'll be able to print.. Let me know if that works now. Cheers – carlesgg97 Nov 29 '19 at 08:08
  • I've tried it, it still show the same, open new window said : Sorry, can not open the file. is it because i input wrong range ? The range i want to print is: i1:N. What changes should i make? – Nguyen Thi Lan Anh Nov 29 '19 at 09:15
  • @NguyenThiLanAnh The current code in my answer prints (or rather, exports to pdf) the data range (i.e. the range of the sheet which has data). There is no option to specify it, although it could be done if you please by changing the line `var range = sheet.getDataRange();` into `var range = sheet.getRange('I1:N');`. Would you still get an error after this modification? Kindly make sure the modification is applied directly to the last version of the code published in my answer. Thanks! – carlesgg97 Nov 29 '19 at 09:20
  • I copy the latest version as you quote above and add 3 changes: 1. put PDF_OPTS in firrst line printSheet() . 2. put 'I1:N' in sheet.getRang('I1:N'). 3. add one } after ar PDF_OPTS = objectToQueryString(PRINT_OPTIONS); row 14 because when i run it said error. But it still show the same error without pdf. Am i doing any thing wrong? – Nguyen Thi Lan Anh Nov 29 '19 at 09:54
  • @NguyenThiLanAnh Could you please show me a screenshot of the error? I am not able to reproduce it. Kindly use imgur or any other image-hosting services to share it... Thanks! – carlesgg97 Nov 29 '19 at 10:09
  • Yes, i capured the desktop but don't know how to show it in comment, so i put it in the answer above. is this ok? – Nguyen Thi Lan Anh Nov 29 '19 at 10:49
  • @NguyenThiLanAnh Kindly consider putting those images on your original question by editing it - the answer section is reserved for actual answers to the original question. Regarding your picture, it seems like your final URL is not being created properly. This seems due to the PDF_OPTS variable not being identified as it should. For me it works with above code. Your final script should look like the one in [this picture](https://i.imgur.com/ToLqLQ4.png). – carlesgg97 Nov 29 '19 at 13:44