문제
구글 시트에는 셀의 값으로 이미지를 넣을 수 있는 기능이 있습니다.
온라인상에 존재하여 일반적인 URL로 접근할 수 있는 경우 IMAGE
함수를 사용하면 됩니다.
=IMAGE("https://blog.te6.in/static/0c71a61fef21d7b1f045572299d5ac09/b529c/404.webp")
문제는 인자로 URL만 넣을 수 있다는 점입니다. 저는 이미지를 base64 인코딩한 텍스트를 다시 디코딩해서 이미지를 넣고 싶었습니다.
준비하기
이 구현은 함수로는 불가능하고, 엑셀로 치면 VBA 포지션인, Apps Script를 사용해야 합니다.
먼저 메뉴 모음에서 확장 프로그램(Extensions) - Apps Script를 선택해 Apps Script 에디터를 열고 새 파일을 하나 생성합니다. 파일 이름은 뭐로 하든 상관없습니다.
B9
셀로 시작하는 범위에서 C열에 존재하는 base64 string을 바탕으로 B열, D열에 이미지를 넣는 코드는 아래와 같습니다.
function putImage(base64String, sheet, cells) {
if (!base64String || typeof base64String !== 'string') {
Logger.log("문제가 있어요");
return;
}
for (const cell of cells){
try {
const image = SpreadsheetApp.newCellImage().setSourceUrl(`data:image/png;base64,${base64String}`).build();
// 이미지를 넣어줍니다
sheet.getRange(cell.row, cell.col).setValue(image);
} catch(error) {
Logger.log(error)
}
}
}
function addImages() {
const currentSheet = SpreadsheetApp.getActive().getActiveSheet();
// B9이 포함된 범위(표)에서 작업합니다.
const availableRows = currentSheet.getRange('B9').getDataRegion().getNumRows();
// 9행부터, B9이 포함된 범위(표)가 끝나는 곳까지 작업합니다.
for (let row = 9; row <= availableRows + 1; row++) {
// base64 문자열은 C9, C10, C11, ...에 있다고 가정합니다.
const cellValue = currentSheet.getRange(row, 3).getValue();
if (!cellValue || cellValue.startsWith("#")) continue;
// B9, B10, B11, ...과 D9, D10, D11, ...에 이미지를 넣고 싶다고 가정하면 이렇게 되겠죠
putImage(cellValue, currentSheet, [{ row, col: 2 }, { row, col: 4 }]);
}
}
사용하기
매크로로 사용하기
확장 프로그램(Extensions) - 매크로(Macros) - 매크로 가져오기(Import Macro) 메뉴로 가면 Apps Script에서 만든 함수를 매크로에 추가할 수 있습니다.
추가한 매크로는 확장 프로그램(Extensions) - 매크로(Macros) 메뉴에서 선택해 실행하거나, 확장 프로그램(Extensions) - 매크로(Macros) - 매크로 관리(Manage Macros)에서 단축키를 부여하여 사용할 수 있습니다.
addImages
함수를 매크로로 등록하면 되겠죠.
도형에 함수 연결하기
엑셀에서 도형에 매크로를 연결할 수 있는 것처럼, 구글 스프레드시트에서도 클릭 가능한 요소에 Apps Script 함수를 추가할 수 있습니다.
- 삽입(Insert) - 그림(Drawing)을 선택해서 도형을 적당히 그립니다.
- 도형을 선택하면 도형을 선택하면 나오는
…
메뉴에서 스크립트 할당(Assign Script)을 선택하고, Apps Script에서 작성한 함수 이름을 그대로 (addImages
) 입력합니다. - 이제 도형을 클릭하면 C열의 string을 바탕으로 B, D열에 이미지가 들어갑니다.
사용 예
저는 구글 시트의 강점인 IMPORTXML
, IMPORTHTML
와 같은 함수를 통해 base64 인코딩된 이미지의 텍스트를 뽑아오고, 해당 매크로를 통해 이미지를 넣고 있습니다. (bradjasper/ImportJSON도 유용합니다)
물론, 셀에 입력하는 함수로서 구현하는 것이 불가능하여 Apps Script로 구현했기 때문에, 인코딩 결과인 텍스트 내용이 달라진다고 해서 바로 이미지가 업데이트되지는 않고, 변경 사항이 생기면 직접 매크로를 실행해야 합니다.