|
function generateCalendar() { |
|
const param = params(); |
|
let targetSS = SpreadsheetApp.openById(param.sheet.targetId); |
|
|
|
for (let month = param.months[0]; month <= param.months[1]; month++) { |
|
let sheetName = `${param.prefix}${param.year}-${String(month).padStart(2, '0')}${param.postfix}`; |
|
let sheet = targetSS.getSheetByName(sheetName); |
|
if (sheet == null) { |
|
sheet = targetSS.insertSheet(); |
|
sheet.setName(sheetName); |
|
} |
|
|
|
// Year |
|
sheet.getRange(param.sheet.layout.year).setValue(param.sheet.yearString); |
|
sheet.getRange(param.sheet.layout.year).setFontSize(param.sheet.fontSize.year); |
|
sheet.getRange(param.sheet.layout.year).setFontWeight("bold"); |
|
sheet.getRange(param.sheet.layout.year).setFontColor(param.sheet.fontColor.default); |
|
|
|
// Month |
|
writeMonthHeader(sheetName, month); |
|
writeWeekHeader(sheetName); |
|
writeDays(sheetName, month); |
|
|
|
// Modify entire format |
|
let dataRange = sheet.getDataRange(); |
|
dataRange.setHorizontalAlignment("left"); |
|
|
|
// Header Image |
|
insertImage(sheetName, param.year, month); |
|
|
|
// Space after the last week. |
|
if (0 < param.sheet.layout.bottomHeaderHight) { |
|
sheet.setRowHeight(dataRange.getLastRow(), param.sheet.layout.bottomHeaderHight); |
|
} |
|
|
|
// Save as PDF |
|
/* |
|
const ssId = targetSS.getId(); |
|
const sheetId = sheet.getSheetId(); |
|
savePDF(ssId, sheetId, sheetName); |
|
*/ |
|
} |
|
} |
|
|
|
function savePDF(ssId, sheetId, sheetName) { |
|
const param = params(); |
|
const folder = DriveApp.getFileById(ssId).getParents().next(); |
|
const fileName = `${sheetName}_${Utilities.formatDate(new Date(), 'JST', 'yyyyMMdd')}.pdf`; |
|
|
|
// Output Options |
|
var opts = { |
|
'exportFormat': 'pdf', // (pdf / csv / xls / xlsx) |
|
'format': 'pdf', // (pdf / csv / xls / xlsx) |
|
'size': `${param.sheet.size}`, |
|
'portrait': 'true', //(true: 縦向き / false: 横向き) |
|
'scale': 4, // //1= Normal 100% / 2= Fit to width / 3= Fit to height / 4= Fit to Page |
|
'sheetnames': 'false', // write the sheet name on the top of sheet(true / false) |
|
'printtitle': 'false', // write the spread sheet name on the top of sheet (true / false) |
|
'pagenumbers': 'false', |
|
'gridlines': 'false', |
|
'fzr': 'false', // write the line number |
|
'horizontal_alignment': 'CENTER', //LEFT/CENTER/RIGHT |
|
'vertical_alignment': 'TOP', //TOP/MIDDLE/BOTTOM |
|
'top_margin': `${param.pdf.top_margin}`, |
|
'bottom_margin': `${param.pdf.bottom_margin}`, |
|
'left_margin': `${param.pdf.left_margin}`, |
|
'right_margin': `${param.pdf.right_margin}`, |
|
}; |
|
|
|
let urlExt = []; |
|
for (optName in opts) { |
|
urlExt.push(optName + '=' + opts[optName]); |
|
} |
|
const options = urlExt.join('&'); |
|
|
|
// OAuth token |
|
var token = ScriptApp.getOAuthToken(); |
|
|
|
// URL |
|
const url = `https://docs.google.com/spreadsheets/d/${ssId}/export?gid=${sheetId}&${options}`; |
|
|
|
// Request to create PDF |
|
var response = UrlFetchApp.fetch( |
|
url, { |
|
headers: { 'Authorization': 'Bearer ' + token } |
|
} |
|
); |
|
|
|
// Create Blob |
|
var blob = response.getBlob().setName(fileName); |
|
|
|
// Save the PDF |
|
folder.createFile(blob); |
|
} |
|
|
|
function writeMonthHeader(sheetName, month) { |
|
const param = params(); |
|
const masterSS = SpreadsheetApp.openById(param.sheet.masterId); |
|
let targetSS = SpreadsheetApp.openById(param.sheet.targetId); |
|
|
|
let sheet = targetSS.getSheetByName(sheetName); |
|
let monthDefSheet = masterSS.getSheetByName(param.sheet.sheetNames.month); |
|
if (monthDefSheet == null) { |
|
Logger.log(`Cannot open ${param.sheet.sheetNames.month}`); |
|
} |
|
const monthLabel = monthDefSheet.getDataRange().getValues(); |
|
const monthHiragana = monthLabel[month - 1][0]; |
|
let mhRange = sheet.getRange(param.sheet.layout.monthHiragana); |
|
mhRange.merge(); |
|
mhRange.setValue(monthHiragana); |
|
mhRange.setFontWeight("bold"); |
|
mhRange.setFontSize(param.sheet.fontSize.monthHiragana); |
|
mhRange.setFontColor(param.sheet.fontColor.default); |
|
|
|
sheet.getRange(param.sheet.layout.monthNum).setValue(monthLabel[month - 1][1]); |
|
sheet.getRange(param.sheet.layout.monthNum).setFontWeight("bold"); |
|
sheet.getRange(param.sheet.layout.monthNum).setFontSize(param.sheet.fontSize.monthNum); |
|
sheet.getRange(param.sheet.layout.monthNum).setFontColor(param.sheet.fontColor.default); |
|
|
|
sheet.getRange(param.sheet.layout.monthEng).setValue(monthLabel[month - 1][2]); |
|
sheet.getRange(param.sheet.layout.monthEng).setFontWeight("bold"); |
|
sheet.getRange(param.sheet.layout.monthEng).setFontSize(param.sheet.fontSize.monthEng); |
|
sheet.getRange(param.sheet.layout.monthEng).setFontColor(param.sheet.fontColor.default); |
|
|
|
sheet.getRange(param.sheet.layout.monthWa).setValue(monthLabel[month - 1][3]); |
|
sheet.getRange(param.sheet.layout.monthWa).setFontWeight("bold"); |
|
sheet.getRange(param.sheet.layout.monthWa).setFontSize(param.sheet.fontSize.monthWa); |
|
sheet.getRange(param.sheet.layout.monthWa).setFontColor(param.sheet.fontColor.default); |
|
|
|
sheet.getRange(param.sheet.layout.season).setValue(monthLabel[month - 1][4]); |
|
sheet.getRange(param.sheet.layout.season).setFontWeight("bold"); |
|
sheet.getRange(param.sheet.layout.season).setFontSize(param.sheet.fontSize.season); |
|
sheet.getRange(param.sheet.layout.season).setFontColor(param.sheet.fontColor.default); |
|
} |
|
|
|
function writeWeekHeader(sheetName) { |
|
const param = params(); |
|
const masterSS = SpreadsheetApp.openById(param.sheet.masterId); |
|
let targetSS = SpreadsheetApp.openById(param.sheet.targetId); |
|
|
|
let sheet = targetSS.getSheetByName(sheetName); |
|
let weekDefSheet = masterSS.getSheetByName(param.sheet.sheetNames.week); |
|
if (weekDefSheet == null) { |
|
Logger.log(`Cannot open ${param.sheet.sheetNames.week}`); |
|
} |
|
const weekRange = sheet.getRange(param.sheet.layout.weekTitle); |
|
const weekLabel = weekDefSheet.getDataRange().getValues(); |
|
|
|
const weekId = []; |
|
for (let w = param.startWeek; w < 7; w++) { |
|
weekId.push(w); |
|
} |
|
for (let w = 0; w < param.startWeek; w++) { |
|
weekId.push(w); |
|
} |
|
|
|
for (let r = 0; r < weekRange.getNumRows(); r++) { |
|
for (let c = 0; c < weekRange.getNumColumns(); c++) { |
|
let cell = weekRange.getCell(r + 1, c + 1); |
|
sheet.setColumnWidth(cell.getColumn(), param.sheet.layout.dayColWidth); |
|
cell.setValue(weekLabel[r][c]); |
|
cell.setFontWeight("bold"); |
|
if (r == 0) { |
|
if (weekId[c] == 0) { |
|
cell.setFontColor(param.sheet.fontColor.sunday); |
|
} else if (weekId[c] == 6) { |
|
cell.setFontColor(param.sheet.fontColor.saturday); |
|
} else { |
|
cell.setFontColor(param.sheet.fontColor.default); |
|
} |
|
cell.setFontSize(param.sheet.fontSize.weekTitle); |
|
} else { |
|
|
|
cell.setFontColor(param.sheet.fontColor.default); |
|
cell.setFontSize(param.sheet.fontSize.weekSubtitle); |
|
} |
|
} |
|
} |
|
} |
|
|
|
function writeDays(sheetName, month) { |
|
const param = params(); |
|
const masterSS = SpreadsheetApp.openById(param.sheet.masterId); |
|
let targetSS = SpreadsheetApp.openById(param.sheet.targetId); |
|
|
|
let sheet = targetSS.getSheetByName(sheetName); |
|
let dayDefSheet = masterSS.getSheetByName(param.sheet.sheetNames.days); |
|
if (dayDefSheet == null) { |
|
Logger.log(`Cannot open ${param.sheet.sheetNames.days}`); |
|
} |
|
const dayLabel = dayDefSheet.getDataRange().getValues(); |
|
let eventDefSheet = masterSS.getSheetByName(param.sheet.sheetNames.events); |
|
if (eventDefSheet == null) { |
|
Logger.log(`Cannot open ${param.sheet.sheetNames.events}`); |
|
} |
|
const eventLabel = eventDefSheet.getDataRange().getValues(); |
|
let calendars = {}; |
|
for (key in param.calendar.ids) { |
|
if (param.calendar.ids.hasOwnProperty(key)) { |
|
let id = param.calendar.ids[key]; |
|
let calendar = CalendarApp.getCalendarById(id); |
|
calendars[key] = calendar; |
|
} |
|
} |
|
const year = param.year; |
|
const firstDayOfWeek = new Date(year, month - 1, 1).getDay(); |
|
let monthLastDay = { 1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31 }; |
|
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { |
|
monthLastDay[2] = 29; |
|
} |
|
let margin = firstDayOfWeek - param.startWeek; |
|
if (margin < 0) { |
|
margin = 6 - param.startWeek - margin; |
|
} |
|
let r = 1; |
|
let c = margin + 1; |
|
let dayRange = sheet.getRange(param.sheet.layout.days); |
|
dayRange.setVerticalAlignment("top"); |
|
for (let day = 1; day <= monthLastDay[month]; day++) { |
|
if (c == 8) { |
|
c = 1; |
|
r += (4 + param.sheet.layout.dayEmptyRows); |
|
} |
|
const date = new Date(year, month - 1, day); |
|
|
|
// Day Number |
|
let cell = dayRange.getCell(r, c); |
|
cell.setValue(dayLabel[day - 1][0]); |
|
cell.setFontSize(param.sheet.fontSize.dayNum); |
|
cell.setFontFamily(param.sheet.font.dayNum); |
|
cell.setFontWeight("bold"); |
|
const weekId = date.getDay(); |
|
let isHoliday = false; |
|
if (0 < CalendarApp.getCalendarById(param.calendar.ids["祝日"]).getEventsForDay(date).length) { |
|
cell.setFontColor(param.sheet.fontColor.sunday); |
|
isHoliday = true; |
|
} else if (weekId == 0) { |
|
cell.setFontColor(param.sheet.fontColor.sunday); |
|
} else if (weekId == 6) { |
|
cell.setFontColor(param.sheet.fontColor.saturday); |
|
} else { |
|
cell.setFontColor(param.sheet.fontColor.default); |
|
} |
|
|
|
// Day Hiragana |
|
cell = dayRange.getCell(r + 1, c); |
|
cell.setValue(dayLabel[day - 1][1]); |
|
cell.setFontSize(param.sheet.fontSize.dayHiragana); |
|
cell.setFontWeight("bold"); |
|
if (weekId == 0 || isHoliday) { |
|
cell.setFontColor(param.sheet.fontColor.sunday); |
|
} else if (weekId == 6) { |
|
cell.setFontColor(param.sheet.fontColor.saturday); |
|
} else { |
|
cell.setFontColor(param.sheet.fontColor.default); |
|
} |
|
|
|
// Day Events |
|
horidayString = ""; |
|
eventString = ""; |
|
for (key in calendars) { |
|
if (calendars.hasOwnProperty(key)) { |
|
const events = calendars[key].getEventsForDay(date); |
|
for (e of events) { |
|
let title = e.getTitle(); |
|
// Convert the event title to customized string defined in SpreadSheet. |
|
// If there is no corresponding definition, the original title is used. |
|
for (let i = 0; i < eventLabel.length; i++) { |
|
if (title == eventLabel[i][0]) { |
|
if (typeof eventLabel[i][1] === 'undefined' || eventLabel[i][1].length == 0) { |
|
title = ""; |
|
break; |
|
} else if (param.mode == 0) { |
|
title = `${eventLabel[i][1]}`; |
|
} else if (param.mode == 1 || param.mode == 2) { |
|
title = `${eventLabel[i][0]}`; |
|
} else { |
|
title = `${eventLabel[i][0]}`; |
|
} |
|
// emoji |
|
if (typeof eventLabel[i][2] !== 'undefined' && 0 < eventLabel[i][2].length) { |
|
title += ` ${eventLabel[i][2]}`; |
|
} |
|
if (param.mode == 2) { |
|
title += `\n(${eventLabel[i][1]})`; |
|
} |
|
break; |
|
} |
|
} |
|
if (0 < title.length) { |
|
if (key == "祝日") { |
|
horidayString += `${title}\n`; |
|
} else { |
|
eventString += `${title}\n`; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
// National Holiday Name |
|
if (isHoliday) { // 0 < horidayString.length |
|
horidayString = horidayString.slice(0, -1); // delete last \n |
|
cell = dayRange.getCell(r + 2, c); |
|
cell.setValue(horidayString); |
|
cell.setFontSize(param.sheet.fontSize.dayEvent); |
|
cell.setFontColor(param.sheet.fontColor.sunday); |
|
} |
|
if (0 < eventString.length) { |
|
eventString = eventString.slice(0, -1); // delete last \n |
|
cell = dayRange.getCell(r + 3, c); |
|
cell.setValue(eventString); |
|
cell.setFontSize(param.sheet.fontSize.dayEvent); |
|
cell.setFontColor(param.sheet.fontColor.default); |
|
} |
|
c++; |
|
} |
|
if (6 <= c) { |
|
r += 4; |
|
} |
|
mark(sheet, r, 6); |
|
} |
|
|
|
function mark(sheet, r, c) { |
|
const param = params(); |
|
const range = sheet.getRange(param.sheet.layout.days); |
|
const markString = `Copyright © 2022 yuukicammy`; |
|
let cell = range.getCell(r, c); |
|
cell.setValue(markString); |
|
cell.setFontColor("#FFFFFF"); |
|
} |
|
|
|
function insertImage(sheetName, year, month) { |
|
const param = params(); |
|
let targetSS = SpreadsheetApp.openById(param.sheet.targetId); |
|
let sheet = targetSS.getSheetByName(sheetName); |
|
let imageCell = sheet.getRange(param.sheet.layout.image); |
|
|
|
// Space for the header image. |
|
sheet.setRowHeight(imageCell.getRow(), param.sheet.layout.imageHight); |
|
imageCell.merge(); |
|
imageCell.setHorizontalAlignment("center"); |
|
imageCell.setVerticalAlignment(param.sheet.layout.imageVerticalAlignment); |
|
|
|
const imageSource = imageSources(month); |
|
if (0 < imageSource.length) { |
|
const image = SpreadsheetApp.newCellImage() |
|
.setSourceUrl(imageSource) |
|
.setAltTextTitle(`${year}-${month}-headerImage`) |
|
.setAltTextDescription(`${year}-${month}-headerImage`) |
|
.build(); |
|
imageCell.setValue(image); |
|
} |
|
} |
|
|
|
function imageSources(month) { |
|
const param = params(); |
|
|
|
if (typeof param.image.urls[month] === 'undefined' || |
|
param.image.urls[month].length == 0) { |
|
if (typeof param.image.ids[month] === 'undefined' || |
|
param.image.ids[month] == 0) { |
|
return ""; |
|
} |
|
const imageFile = DriveApp.getFileById(param.image.ids[month]); |
|
const blob = imageFile.getBlob(); |
|
const ctype = blob.getContentType(); |
|
const base64 = Utilities.base64Encode(blob.getBytes()); |
|
return `data:${ctype};base64, ${base64}`; |
|
} else { |
|
return param.image.urls[month]; |
|
} |
|
} |