[정보] IT정보&활용 2024. 10. 23. 18:56

[구글 Apps Script] PDF로 출력하기

반응형

[구글 스프레드 시트]로 일지를 만든 경우, 이 일지의 날짜를 하나하나 변경하면서 PDF로 출력해 저장해주는 스크립트 입니다.

이 모두를 묶어서 하나의 PDF로 구현하는 것을 고민하였으나, 아직까지 구글에서는 PDF 합치기 기능은 제공하고 있지 않는거 같습니다.

 

메뉴바에 출력 버튼이 만들어지고, 적용 월을 입력하면, 그 달에 해당하는 일지를 모두 PDF로 만들어줍니다.

단, 한꺼번에 많은 양을 PDF로 변환하면 구글에서 오류 메시지를 나타내었습니다.

해서 10개씩 출력한 후 30초 기다렸다가 다시 출력하도록 했습니다.

그래서 모두 PDF로 변환되는데 3분 안쪽의 시간이 필요합니다.

// 이후의 각주를 참고하셔서 자신의 시트에 맞게 수정해서 사용하시면 됩니다.

또한 PDF가 저장될 폴더에 접근 권한을 열어 두는거 잊지마세요~

 

----------------------------------

Code.gs

----------------------------------

function onOpen() {

  var ui = SpreadsheetApp.getUi();

  ui.createMenu('출력')

    .addItem('월 입력', 'generatePDFsByMonth')

    .addToUi();

}

 

function generatePDFsByMonth() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();

  var sheet1Name = 'DATA';

  var sheet2Name = '일지'; // 출력서식이 있는 시트명을 정확히 지정해주세요.

  var dateCell = 'A3'; // '일지' 시트에서 날짜가 입력되는 셀입니다.

  var outputRange = 'A1:G25'; // '일지' 시트의 출력범위를 조정합니다.

  var dataRange = 'A2:A'; // 'DATA'시트에서의 날짜 데이터 범위

  var folderId = '1OlXGiKJyeixZ0j4PLIkWl1xxffBZVQZ0'; // PDF가 저장될 폴더의 ID입니다.

 

  var sheet1 = ss.getSheetByName(sheet1Name);

  var sheet2 = ss.getSheetByName(sheet2Name);

  var folder = DriveApp.getFolderById(folderId);

  var ui = SpreadsheetApp.getUi();

  var response = ui.prompt('월을 입력하세요 (YYYY-MM)', ui.ButtonSet.OK_CANCEL);

 

  if (response.getSelectedButton() == ui.Button.OK) {

    var month = response.getResponseText().trim();

    var data = sheet1.getRange(dataRange + sheet1.getLastRow()).getValues();

    var filteredData = data.filter(function(row) {

      return row[0] && formatDate(row[0]).includes(month);

    });

 

    for (var i = 0; i < filteredData.length; i += 10) {

      var chunk = filteredData.slice(i, i + 10);

      chunk.forEach(function(row) {

        sheet2.getRange(dateCell).setValue(formatDate(row[0]));

        SpreadsheetApp.flush();

        Utilities.sleep(1000); // 데이터를 로드하는 데 충분한 시간을 두기 위해 1초 대기

        var pdfBlob = createPDF(sheet2, formatDate(row[0]) + '_' + sheet2Name + '.pdf', outputRange, folder);

        folder.createFile(pdfBlob);

      });

      Utilities.sleep(30000); // 10개의 파일 생성 후 30초 대기

    }

 

    if (filteredData.length > 0) {

      ui.alert('PDF 저장이 완료되었습니다: ' + month);

    } else {

      ui.alert('입력된 월에 해당하는 데이터가 없습니다: ' + month);

    }

  }

}

 

function formatDate(date) {

  var d = new Date(date);

  var year = d.getFullYear();

  var month = ('0' + (d.getMonth() + 1)).slice(-2);

  var day = ('0' + d.getDate()).slice(-2);

  return year + '-' + month + '-' + day;

}

 

function createPDF(sheet, fileName, range, folder) {

  var sheetName = sheet.getName();

  var url = 'https://docs.google.com/spreadsheets/d/' + SpreadsheetApp.getActiveSpreadsheet().getId() +

            '/export?exportFormat=pdf&format=pdf' +

            '&size=A4' +

            '&portrait=true' +

            '&fitw=true' +

            '&sheetnames=false&printtitle=false' +

            '&pagenumbers=false' +

            '&gridlines=false' +

            '&fzr=false' +

            '&gid=' + sheet.getSheetId() +

            '&range=' + range;

 

  var token = ScriptApp.getOAuthToken();

  var response = UrlFetchApp.fetch(url, {

    headers: {

      'Authorization': 'Bearer ' + token

    }

  });

 

  var pdfBlob = response.getBlob().setName(fileName);

  return pdfBlob;

}



반응형