검색결과 리스트
전체 글에 해당되는 글 784건
- 2024.10.23 [구글 Apps Script] PDF로 출력하기
- 2024.09.30 구글 Apps Script로 후원신청서 만들기 3
- 2024.09.23 Apps Script를 활용해 스프레드 시트로 데이터 전송하기
- 2024.08.27 [구글 스프레드 시트] 서명받기
- 2024.07.28 구글 스프레드 시트로 데이터 분석하기 1
글
[구글 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;
}
'[정보] IT정보&활용' 카테고리의 다른 글
PDF 나누기(split) (2) | 2024.11.06 |
---|---|
PDF 파일 합치기(수정) (1) | 2024.11.01 |
[구글 스프레드 시트] 서명받기 (0) | 2024.08.27 |
컴퓨터 예약 종료 배치파일(.bat) 만들기 (0) | 2024.06.21 |
yt-dlp를 쉽게... 배치파일(bat) 만들기 (0) | 2024.05.29 |
설정
트랙백
댓글
글
구글 Apps Script로 후원신청서 만들기
구글 Apps Script로 입력폼을 만들고, 입력된 데이터들이 구글 스프레드 시트에 저장되도록 하는 스크립트를 구현해 보았습니다.
Apps Script는 두 개의 파일로 작동합니다.
Code.gs라는 이름의 스크립트 파일과 웹화면을 통해 보여질 index.html이 그것입니다.
※ 이 스크립트는 기본적으로 구글 스프레드 시트의 Apps Script를 다룰 줄 아는 사람을 대상으로 하기 때문에 스크립트 적용 이전단계에 대해서는 설명하지 않습니다.
Code.gs
// 스프레드시트 ID와 시트 이름, 서명이미지 저장 폴더 ID를 변수로 선언
var SPREADSHEET_ID = ' YOUR_SPREADSHEET_ID';
var SHEET_NAME = '시트1';
var FOLDER_ID = ' YOUR_FOLDER_ID';
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function sendUserData(name, gender, ssn_a, ssn_b, cphone_n, phone_n, address, e_mail, s_term, s_type, s_money, s_how, s_item, s_item_q, s_unit, s_sector, s_why, s_path, receipt1, receipt2, a_date, signature) {
var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
var imageUrl = saveSignatureToDrive(signature, name);
sheet.appendRow([
name, gender, ssn_a, ssn_b,
"'" + cphone_n, // 앞에 작은 따옴표 추가
"'" + phone_n, // 앞에 작은 따옴표 추가
address, e_mail, s_term, s_type, s_money, s_how,
s_item, s_item_q, s_unit, s_sector, s_why, s_path,
receipt1, receipt2, a_date, '=IMAGE("' + imageUrl + '")'
]);
}
function saveSignatureToDrive(signature, name) {
var folder = DriveApp.getFolderById(FOLDER_ID);
var blob = Utilities.newBlob(Utilities.base64Decode(signature.split(',')[1]), 'image/png', name + '_signature.png');
var file = folder.createFile(blob);
var fileId = file.getId();
}
|
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<title>부민노인복지관 후원신청서</title>
<script src="https://cdn.jsdelivr.net/npm/signature_pad@5.0.3/dist/signature_pad.umd.min.js"></script>
<style>
#sig {
background-color: #e0e0e0;
border: 1px solid black;
width: 500px;
height: 300px;
}
#s_item_q, #ssn_a {
width: 6em;
}
#ssn_b {
width: 7em;
}
#savingMessage {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
border: 1px solid black;
padding: 20px;
z-index: 1000;
}
</style>
</head>
<body>
<p>부민노인복지관 후원신청서</p>
<form id="donationForm">
<label>이름</label>
<input type="text" id="name" name="name" placeholder="이름" required><br>
<label>성별</label>
<input type="radio" name="gender" value="남">남자
<input type="radio" name="gender" value="여">여자<br>
<label>주민등록번호</label>
<input type="text" id="ssn_a" name="ssn_a" size="6" maxlength="6" required>-
<input type="password" id="ssn_b" name="ssn_b" size="7" maxlength="7" required><br>
<label>휴대전화</label>
<input type="text" id="cphone_n" name="cphone_n" size="11" maxlength="11"> ※ 숫자만 입력<br>
<label>일반전화</label>
<input type="text" id="phone_n" name="phone_n" size="11" maxlength="11"> ※ 숫자만 입력<br>
<label>주소</label>
<input type="text" id="address" name="address" size="30"><br>
<label>이메일</label>
<input type="text" id="e_mail" name="e_mail" size="30"><br>
<label>후원방식</label>
<input type="radio" name="s_term" value="정기">정기
<input type="radio" name="s_term" value="비정기">비정기<br>
<label>후원구분</label>
<input type="radio" name="s_type" value="지정">지정
<input type="radio" name="s_type" value="비지정">비지정<br>
<label>후원금</label>
<input type="text" id="s_money" name="s_money">원<br>
<label>후원방법</label>
<input type="radio" name="s_how" value="자동이체">자동이체
<input type="radio" name="s_how" value="현금납부">현금납부
<input type="radio" name="s_how" value="CMS">CMS 이체
<input type="radio" name="s_how" value="기타">기타<br>
<label>후원품</label>
(품명) <input type="text" id="s_item" name="s_item"> /
(수량) <input type="number" id="s_item_q" name="s_item_q" size="4"> /
(단위) <select id="s_unit" name="s_unit">
<option value="">---</option>
<option value="개">개</option>
<option value="세트">세트</option>
<option value="Box">Box</option>
<option value="건">건</option>
<option value="Kg">Kg</option>
<option value="명">명</option>
<option value="포">포</option>
<option value="g">g(그램)</option>
<option value="리터">리터</option>
<option value="대">대</option>
<option value="장">장</option>
<option value="통">통</option>
<option value="판">판</option>
<option value="병">병</option>
<option value="마리">마리</option>
<option value="봉지">봉지</option>
<option value="팩">팩</option>
<option value="묶음">묶음</option>
<option value="그루">그루</option>
<option value="송이">송이</option>
<option value="포기">포기</option>
<option value="자루">자루</option>
<option value="인분">인분</option>
<option value="짝">짝</option>
<option value="포대">포대</option>
<option value="기타">기타</option>
</select><br>
<label>후원분야</label>
<select id="s_sector" name="s_sector">
<option value="">---------</option>
<option value="밑반찬지원">밑반찬지원</option>
<option value="저소득노인 무료급식사업">저소득노인 무료급식사업</option>
<option value="위기 및 취약노인 사업">위기 및 취약노인 사업</option>
<option value="지역복지 연계사업">지역복지 연계사업</option>
<option value="명절 정나눔 행사">명절 정나눔 행사</option>
<option value="기타">기타</option>
</select><br>
<label>참여동기</label>
<select id="s_why" name="s_why">
<option value="">---------</option>
<option value="경제적 여유가 있어서">경제적 여유가 있어서</option>
<option value="불우한 이웃을 돕기위해">불우한 이웃을 돕기위해</option>
<option value="지역사회복지를 위해">지역사회복지를 위해</option>
<option value="종교적 신념으로">종교적 신념으로</option>
<option value="기타">기타</option>
</select><br>
<label>참여경로</label>
<select id="s_path" name="s_path">
<option value="">---------</option>
<option value="기존 후원자/자원봉사자 소개를 통해">기존 후원자/자원봉사자 소개를 통해</option>
<option value="복지관 소식지나 안내물을 통해">복지관 소식지나 안내물을 통해</option>
<option value="언론매체를 통해">언론매체를 통해(TV, 라디오, 신문 등)</option>
<option value="특정 행사 및 기념일 축하">특정 행사 및 기념일 축하</option>
<option value="기타">기타</option>
</select><br>
<label>후원금영수증 발급</label><br>
<input type="checkbox" name="receipt1" value="후원금영수증 필요">후원금 영수증 필요<br>
<input type="checkbox" name="receipt2" value="국세청 연말정산 간소화 후원내역 제공 동의">국세청 연말정산 간소화 후원내역 제공 동의 <br>
<label>신청일자</label>
<input type="date" id="a_date" name="a_date"><br>
<label>서명</label><br>
<canvas id="sig"></canvas><br>
<button type="button" id="clearSig">서명 지우기</button><br><br>
<button type="button" onclick="submitData()">제출</button>
</form>
<div id="savingMessage">저장 중입니다...</div>
<script>
var signaturePad;
function setupSignatureBox() {
var canvas = document.getElementById("sig");
canvas.width = 500; // 명시적으로 크기 설정
canvas.height = 300; // 명시적으로 크기 설정
signaturePad = new SignaturePad(canvas);
}
function clearSignature() {
signaturePad.clear();
}
function submitData() {
const form = document.getElementById('donationForm');
const formData = new FormData(form);
// 필수 입력 필드 확인
if (!formData.get('name') || !formData.get('ssn_a') || !formData.get('ssn_b') || !formData.get('cphone_n') || signaturePad.isEmpty()) {
alert('성명, 주민등록번호, 서명은 필수 입력 항목입니다.');
return;
}
const data = {
name: formData.get('name'),
gender: formData.get('gender'),
ssn_a: formData.get('ssn_a'),
ssn_b: formData.get('ssn_b'),
cphone_n: formData.get('cphone_n'),
phone_n: formData.get('phone_n'),
address: formData.get('address'),
e_mail: formData.get('e_mail'),
s_term: formData.get('s_term'),
s_type: formData.get('s_type'),
s_money: formData.get('s_money'),
s_how: formData.get('s_how'),
s_item: formData.get('s_item'),
s_item_q: formData.get('s_item_q'),
s_unit: formData.get('s_unit'),
s_sector: formData.get('s_sector'),
s_why: formData.get('s_why'),
s_path: formData.get('s_path'),
receipt1: formData.get('receipt1') ? '필요' : '불필요',
receipt2: formData.get('receipt2') ? '동의' : '미동의',
a_date: formData.get('a_date'),
signature: signaturePad.toDataURL()
};
document.getElementById('savingMessage').style.display = 'block'; // 저장 중 메시지 표시
google.script.run.withSuccessHandler(() => {
document.getElementById('savingMessage').style.display = 'none'; // 저장 중 메시지 숨기기
alert('데이터가 성공적으로 저장되었습니다.');
}).withFailureHandler(error => {
document.getElementById('savingMessage').style.display = 'none'; // 저장 중 메시지 숨기기
console.error('Error:', error);
alert('데이터 저장 중 오류가 발생했습니다. 다시 입력해주세요.');
}).sendUserData(
data.name, data.gender, data.ssn_a, data.ssn_b, data.cphone_n, data.phone_n,
data.address, data.e_mail, data.s_term, data.s_type, data.s_money, data.s_how,
data.s_item, data.s_item_q, data.s_unit, data.s_sector, data.s_why, data.s_path,
data.receipt1, data.receipt2, data.a_date, data.signature
);
}
document.getElementById("clearSig").addEventListener("click", clearSignature);
document.addEventListener("DOMContentLoaded", setupSignatureBox);
</script>
</body>
</html>
|
입력 폼은 아래 링크와 같이 보여지게 됩니다.
https://script.google.com/a/macros/bmsenior.org/s/AKfycbxOwy1AJqVZypRUhlJtNl3xzWDSm4mUWhKxtBwI0_FrT66QLX_6ruxFn0h0WR4JUYrA3w/exec
script.google.com
'[楞嚴] 생각 나누기 > [情] 사회복지정보화' 카테고리의 다른 글
Apps Script를 활용해 스프레드 시트로 데이터 전송하기 (0) | 2024.09.23 |
---|---|
폰트 저작권 이슈에 대한 점검 (0) | 2020.08.12 |
코로나19 상황에 대한 전화설문조사 결과 (0) | 2020.07.08 |
QR코드를 활용한 출입자 관리 - 노인복지관용 (3) | 2020.06.24 |
ⓝ세대 가족을 위한 사이버복지관의 설립과 역할 (0) | 2017.01.05 |
설정
트랙백
댓글
글
Apps Script를 활용해 스프레드 시트로 데이터 전송하기
우리가 입력하는 데이터를 구글 스프레드 시트에 저장되게 하려면 어떻게 해야할까요?
기본적으로 구글 설문지 폼을 사용하면 스프레드 시트에 저장되는 것을 확인할 수 있습니다.
이걸 내가 원하는 대로 할 수는 없을까요?
일반적으로 생각했을 때 2개의 서식이 필요하단 사실은 떠올릴 수 있을 것입니다.
첫번째로 데이터를 입력하는 서식이며, 이는 웹 화면을 통해 보여질 것입니다.
구글 스프레드시트의 Apps Script에서는 기본값으로 index.html을 설정해두고 있습니다.
두번째로 입력된 데이터가 스프레드 시트에 차곡차곡 쌓여야할 것입니다.
이를 위한 스프레드 시트 파일(SpreadSheet)이 필요합니다.
그런데 하나가 더 필요합니다.
이 두 파일을 연결할 연결고리, 그것이 Apps Script 입니다.
Code.gs가 바로 그것입니다.
자, 정리하자면, 데이터입력을 담당하는 index.html, 데이터를 받아서 저장할 SpreadSheet, 마지막으로 이 둘을 연결하는 Code.gs가 필요합니다.
이때 필요한 가장 기본적인 코드를 정리해보겠습니다.
- index.html
<!DOCTYPE html> <html> <head> <base target="_top"> <!-- 아래 스크립트를 통해 구글 스프레드 시트에 저장하게 됩니다. --> <script> function onSuccess(){ alert("저장완료"); } function resister() { let inputEl = document.getElementsByTagName("input"); let inputData = []; for(element of inputEl) { inputData.push(element.value); } google.script.run.withSuccessHandler(onSuccess).sendUserData(inputData); } </script> <!-- 여기까지 --> </head> <body> <p>데이터 입력</p> <!-- 아래 input 태그를 통해 데이터가 입력되며, resister()를 통해 등록됩니다. --> <label>종류</label> <input type="text" name="type"><br> <label>수량</label> <input type="number" name="number"><br> <label>유효기간</label> <input type="date" name="deadline"><br> <button onclick="resister()">등록</button> <!-- 여기까지. 위에 input은 더 많이 추가해도 됩니다. --> </body> </html> |
- Code.gs
- index.html과 소통하기 위해 필요한 함수
function doGet() { return HtmlService.createHtmlOutputFromFile('index'); } |
- 아래 3개 중 필요에 따라 선택
function sendUserData(inputData) { let ss = SpreadsheetApp.getActiveSheet(); ss.appendRow(inputData); } |
▲ 구글 스프레드 시트에서 바로 App Script를 만든 경우로 시트가 하나 뿐인 경우. 별도의 지정없이 바로 작동합니다. |
function sendUserData(inputData) { let sheetName = '시트1'; // 시트 이름을 변수로 선언 let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); ss.appendRow(inputData); } |
▲ 시트가 여러개인 경우 시트명을 변수로 지정토록 하였습니다. ’시트1’을 수정하세요. |
function sendUserData(inputData) { // 스프레드시트 파일 ID 및 시트 이름 설정 const spreadsheetId = 'YOUR_SPREADSHEET_ID'; // 여기에 스프레드시트 파일 ID를 입력 const sheetName = '시트1'; // 스프레드시트 및 시트 가져오기 const spreadsheet = SpreadsheetApp.openById(spreadsheetId); const sheet = spreadsheet.getSheetByName(sheetName); // 데이터 추가 sheet.appendRow(inputData); } |
▲ 파일명(고유ID)와 시트명을 모두 변수로 설정합니다. ’YOUR_SPREADSHEET_ID’에 스프레드 시트 파일의 ID를 직접 입력합니다. ’시트1’에 시트명을 직접 입력합니다. |
여기까지가 기본적인 처리방법입니다.
index.html을 수정함으로써 입력화면을 좀더 다양하게 꾸밀 수 있으며, 스프레드 시트로 보낼 데이터도 추가할 수 있을 것입니다.
'[楞嚴] 생각 나누기 > [情] 사회복지정보화' 카테고리의 다른 글
구글 Apps Script로 후원신청서 만들기 (3) | 2024.09.30 |
---|---|
폰트 저작권 이슈에 대한 점검 (0) | 2020.08.12 |
코로나19 상황에 대한 전화설문조사 결과 (0) | 2020.07.08 |
QR코드를 활용한 출입자 관리 - 노인복지관용 (3) | 2020.06.24 |
ⓝ세대 가족을 위한 사이버복지관의 설립과 역할 (0) | 2017.01.05 |
설정
트랙백
댓글
글
[구글 스프레드 시트] 서명받기
appsscript활용
4 대상자 검색,수정,추가하기1 동영상 대상자 검색,수정,추가하기2 동영상 대상자 검색,수정,추가하기3 동영상 대상자 검색,수정,추가하기4 동영상 대상자 검색,수정,추가하기5 동영상 대상자 검
swsp.or.kr
여기에 가보면 구글 스프레드 시트 의 앱 스크립트를 활용한 다양한 사례들을 보여주고 있다.
그 중 주목한 것 하나가 바로 "서명받기"
후원신청서나 프로그램 참가 신청을 받을 때에도 유용할 거 같아서 좀더 자세히 살펴보았다.
소스는 다 오픈되어 있어 하나하나 뜯어보면서 나에게 필요한 방식으로 수정해보았다.
여기에 입력하면,
https://docs.google.com/spreadsheets/d/13EJTaSd31_r8A8I4v6WzGqr1BJfqsmVmu4Xv55IpZpw/edit?gid=0#gid=0
여기에 이름과, 서명이미지, 그리고 해당 이미지의 url을 저장해 보여준다.
그런데 이 걸 내가 사용하기 위해서는 몇가지 수정해야할 것이이 있다.
서명이 저장되는 ① 구글 스프레드 시트의 고유 ID를 알아야하고, ② 서명 이미지가 저장될 폴더의 고유 ID를 알아야 한다.
마지막으로 ③ 저장될 시트의 이름도 일치시켜야 한다.
그래서 내가 편하려고 소스를 좀 수정해보았다.
1. Code.gs
function doGet() {
return HtmlService.createTemplateFromFile("index").evaluate();
}
function receiveSiganture(encodedImage,signame){
// 폴더, 스프레드시트 ID 및 시트명을 직접 입력해주세요.
const folderId = "23GF3aHMo0MDOxjCQLss12Ir-WjQmQT_T7B9";
const spreadsheetId = "2Ak0WTqcdsc25RcaQZ86dRNMbddcOn88_eIdo";
const sheetName = "시트1";
var fileTime = new Date();
var s1 = signame.sigName;
const data = encodedImage.split(",")[1];
const dataDecoded = Utilities.base64Decode(data);
const signatureAsPictureBlob = Utilities.newBlob(dataDecoded).setName(s1+fileTime+"somefile.png");
// 서명이 저장될 폴더
var signurl = DriveApp.getFolderById(folderId).createFile(signatureAsPictureBlob).getId();
var signfile2 = "https://drive.google.com/drive/folders/" + folderId + "/uc?export=view&id=" + signurl;
// 입력된 서명 정보가 저장될 스프레드 시트
var sa = SpreadsheetApp.openById(spreadsheetId);
var sheet1 = sa.getSheetByName(sheetName);
var rowData = [[fileTime, s1, signfile, signfile2]];
var lastRow = sheet1.getLastRow();
sheet1.getRange(lastRow+1, 1, 1, 4).setValues(rowData);
getTexttS();
}
function getTexttS(form){
var text = "서명이 입력되었습니다.";
return text;
}
|
이제 위 음영처리한 ID와 이름만 정확히 확인해서 입력하면, 다른 소스는 수정할 필요가 없다.
2. index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>서명받기</title>
</head>
<body>
<form id="signatureForm">
<div id="app" class="container">
<h2>성함을 입력하시고 아래 패드에 서명해 주세요.</h2><br><br>
성명: <input type="text" name="mname" id="mname"><br><br>
<div class="">
<canvas id="sig" style="background-color: #e0e0e0; border: 1px solid black; width: 500px height: 300px;">
</canvas>
</div>
<div>
<button type="button" id="clearSig">Clear</button>
<button type="button" id="send">Send</button>
</div>
</div>
<input type="hidden" id="mtext" name="mtext">
</form>
<!-- 서명패드 스크립트: 오픈소스이며, 무료입니다. 아래는 원본 링크 -->
<script src="https://cdn.jsdelivr.net/npm/signature_pad@5.0.3/dist/signature_pad.umd.min.js"></script>
<script>
var signaturePad
function setupSignatureBox(){
var canvas = document.getElementById("sig");
signaturePad = new SignaturePad(canvas);
}
function clearSignature(){
signaturePad.clear();
}
function sendToDrive(){
if(mname.value.length == 0){
alert("성명을 입력하세요");
mname.focus();
} else {
var imageData = signaturePad.toDataURL();
var signame = {sigName: document.getElementsByName('mname')[0].value};
google.script.run.receiveSiganture(imageData, signame);
google.script.run.withSuccessHandler(getText).getTexttS(document.forms[0]);
setTimeout('note()', 2000);
clearSignature()
// console.log(imageData);
}
}
function note(){
var alt = document.getElementById('mtext').value;
alert(alt);
document.getElementById("signatureForm").reset();
}
function getText(text){
var txtTextt = document.getElementById('mtext');
txtTextt.value = text;
}
document.getElementById("clearSig").addEventListener("click",clearSignature);
document.getElementById("send").addEventListener("click",sendToDrive);
document.addEventListener("DOMContentLoaded",setupSignatureBox);
</script>
</body>
</html>
|
원본에서는 1개의 css 파일과 2개의 js 파일을 참조토록 하고 있었다.
하지만 굳이 디자인이 복잡할 필요가 있는게 아니라서 과감히 삭제했다.
그리고 꼭 필요한 서명용 js 파일을 확인하고, 원본 사이트에 들어가 가장 최신의 스크립트로 교체하였다.
github에서 배포되고 있으며, 확인결과 상업적 사용까지 무료인 것을 확인하였다.
https://github.com/szimek/signature_pad
GitHub - szimek/signature_pad: HTML5 canvas based smooth signature drawing
HTML5 canvas based smooth signature drawing. Contribute to szimek/signature_pad development by creating an account on GitHub.
github.com
그리고 이를 웹에서 링크로 사용할 수 있도록 제공하는 url은 위와 같다.
사실 gemini에게 물어보면 굳이 링크에 있는 스크립트를 사용하지 않아도 이미지를 그릴 수 있는 소스를 만들어준다.
1. Code.gs
// 그리기 기능
function doGet() {
var html = HtmlService.createHtmlOutputFromFile('index');
return html;
}
// 지우개 기능 (선의 색을 흰색으로 설정)
function erase() {
ctx.strokeStyle = 'white';
// 드로잉 로직과 동일하게 사용
}
|
2. index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
성명: <input type="text" name="ur_name" id="ur_name"><br><br>
<input type="hidden" id="n_text" name="n_text">
<canvas id="myCanvas" style="background-color: #e0e0e0; border: 1px solid black; width: 500px height: 300px;"></canvas>
<button id="saveButton">저장</button>
<button id="clearButton">지우기</button>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;
function startDrawing(e) {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
}
function draw(e) {
if (!isDrawing) return;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
}
function stopDrawing() {
isDrawing = false;
}
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
// 터치 이벤트 추가 (모바일 지원)
canvas.addEventListener('touchstart', startDrawing);
canvas.addEventListener('touchmove', draw);
canvas.addEventListener('touchend', stopDrawing);
// 지우기 버튼 클릭 이벤트 처리
const clearButton = document.getElementById('clearButton');
clearButton.addEventListener('click', () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
</script>
</body>
</html>
|
처음의 드로잉처럼 자연스럽진 않지만, 그래도 웬만큼 흉내는 된다.
이걸 다시 세세한 부분을 손봐야하는데, 귀찮아서... ㅡ.ㅡ
'[정보] IT정보&활용' 카테고리의 다른 글
PDF 파일 합치기(수정) (1) | 2024.11.01 |
---|---|
[구글 Apps Script] PDF로 출력하기 (0) | 2024.10.23 |
컴퓨터 예약 종료 배치파일(.bat) 만들기 (0) | 2024.06.21 |
yt-dlp를 쉽게... 배치파일(bat) 만들기 (0) | 2024.05.29 |
한글, ( )안의 글자만 모양 바꾸기 (0) | 2023.03.30 |
설정
트랙백
댓글
글
구글 스프레드 시트로 데이터 분석하기
구글 스프레드 시트를 이용해 데이터를 분석할 수 있도록 만들어 보았습니다.
2024.05.27 - [[楞嚴] 생각 나누기/[平] 사회조사와 데이터분석] - Excel로 통계분석하기 #3
Excel로 통계분석하기 #3
Excel(엑셀)은 데이터 분석을 위해, 추가기능을 통해 분석도구를 제공하고 있다.2021.11.07 - [[정보] 복지 이야기/[福] 복지 배우기] - Excel로 통계분석하기 #1 Excel로 통계분석하기 #1굳이 비싼 통계 프
welfareact.net
이전에도 엑셀로 통계분석하는 파일을 만들기도 하였지만, 해당 파일은 결측값이 있는 경우에 대한 반영이 정확히 되어 있지 않습니다.
이번 버전에서는 결측값에 대한 처리를 SPSS의 결과 값과 비교하면서 보완을 해보았습니다.
https://docs.google.com/spreadsheets/d/1bvD_d5KbLt4yeyXHhg6FfbowdwjgjQHWTroWbvNYyag/edit?usp=sharing
데이터 분석
목차 구글 스프레드 시트로 데이터 분석하기 by,정수홍, jshever@hanmail.net <a href="http://welfareact.net/">https://welfareact.net</a> update 2024. 7. 27. 목차,DATA set,활용 <a href="#gid=1653135853">영가설 기각의 의미</a>,<a
docs.google.com
현재 모수검정 중 구현이 가능한 부분은 완료한 상태이며,
추가로 비모수검정인 순위상관분석과 카이제곱검정은 어떻게 하면 좋을지 검토 중에 있습니다.
추가로 비모수 검정인 순위상관분석과 카이제곱검정을 추가하였습니다.(2024. 9. 1)
혹시 오류가 있다면 알려주시면 반영해보겠습니다.
이 문서의 활용은 Data Set에 분석할 데이터를 입력하시면 됩니다.
직접 수식을 수정해보시려면 "사본 만들기"를 하셔 테스트해보세요~
'[楞嚴] 생각 나누기 > [平] 사회조사와 데이터분석' 카테고리의 다른 글
다중응답에 대한 카이제곱(χ²) 검정 방법 by SPSS (0) | 2024.06.02 |
---|---|
Excel로 통계분석하기 #3 (0) | 2024.05.27 |
알아두면 쓸모있는 통계관련 잡학상식 (0) | 2023.12.11 |
표본오차(sampling error) (2) | 2023.11.01 |
리커트(Likert) 척도는 서열척도인가? (0) | 2023.11.01 |
RECENT COMMENT