#JP81 Membuat Website Generator Sertifikat Custom Google Apps Script (Responsive)

Membuat Website Generator Sertifikat custom Menggunakan Google Apps Script (Auto Number)



1. Copy Spreadsheet (Klik Disini)

Contoh Template Sertifikat bisa download disini (Template Sertifikat.zip)


2. Pada Spreadsheet yang telah di copy di atas terdapat 1 sheet Data dan 2 kolom yaitu :

  • Kolom A : Nomor Sertifikat (Judul dibiarkan kosong untuk membaca array angka)
  • Kolom B : Nama Lengkap

3. Buatlah lembar kerja Apps Script dengan cara klik menu Ekstensi/Extensions lalu pilih Apps Script.


4. Pada lembar kerja Apps Script terdapat 3 file default yaitu :
  • Code.gs
  • Index.html
  • Visit.html

5. Copy dan pastekan script di bawah ini ke Code.gs

Masukkan Password Untuk Melihat Script (Password ada di dalam video)

// Source Code www.javabitpro.com


var sheetName = "Data";

function doGet() {
  return HtmlService.createTemplateFromFile('Index').evaluate()
      .setTitle('Javabitpro')
      .addMetaTag('viewport','width=device-width , initial-scale=1')
        .setFaviconUrl('https://i.imgur.com/thmO7Xv.png'); // Ganti URL favicon sesuai kebutuhan
        
}
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}

function updateData(name, number) {
  var sheet = getSheet();
  var lastRow = sheet.getLastRow() + 1;

  if (!number) {
    // Jika Nomor tidak dikirim, berarti kita akan mengambil Nomor terakhir dan menambahkannya
    var lastNumber = sheet.getRange(lastRow - 1, 1).getValue();
    number = lastNumber + 1;
  }

  sheet.appendRow([number, name]);
  
  return "Data berhasil disimpan denan Nama: " + name;
}

function getLatestData() {
  var sheet = getSheet();
  var lastRow = sheet.getLastRow();

  // Jika hanya ada satu baris (header), kembalikan nilai default
  if (lastRow < 2) {
    return ["", ""];
  }

  var number = sheet.getRange(lastRow, 1).getValue();
  var name = sheet.getRange(lastRow, 2).getValue();

  return [number, name];
}

function getSheet() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName(sheetName);

  if (!sheet) {
    sheet = spreadsheet.insertSheet(sheetName);
    sheet.appendRow(['Nomor', 'Name']);
  }

  return sheet;
}


6. Copy dan pastekan script di bawah ini ke Index.html

Masukkan Password Untuk Melihat Script (Password sama dengan di atas)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Original Source Code www.javabitpro.com -->
<!-- Menggunakan Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- font-awesome@6.2.0 icon Visit -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
<?!= include('Visit', {class: 'exclude-from-print'})?>
<style>
body {
	margin:0;
	padding:0;
	height:100vh;
	display:flex;
	align-items:center;
	justify-content:center;
	font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;
}
.container {
	margin-top:0px;
	border:1px solid #ddd;
	border-radius:5px;
	box-shadow:0 0 10px rgba(0,0,0,0.1);
}
@media (min-width:768px) {
	body {
		justify-content:center;
		margin-top: 50px;
	}
}
canvas {
	width:100%;
	/* Lebar canvas mengikuti lebar container */
	height:auto;
	/* Tinggi canvas menyesuaikan proporsi */
	display:block;
	margin:20px 0;
	/* Beri sedikit margin di atas dan bawah canvas */
}
#download-btn,#print-btn {
	display:none;
}
.popup {
	display:none;
	position:fixed;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	background-color:#fff;
	padding:20px;
	border:1px solid #ccc;
	box-shadow:0 0 10px rgba(0,0,0,0.2);
	z-index:999;
}
.close {
	color:#000;
	float:right;
	font-size:20px;
	font-weight:bold;
}
.close:hover {
	color:#f00;
	cursor: pointer;
}
@media print {
	.container {
		width:100%;
		/* Lebar penuh saat mencetak */
		transform:none;
		/* Hapus transformasi skala saat mencetak */
		border:none;
	}
	canvas {
		margin:0;
		/* Hilangkan margin saat mencetak */
	}
	@page {
		size:A4 landscape;
		/* Set ukuran halaman ke A4 landscape */
	}
	h1,h3,h4,input,label,#download-btn,#print-btn,button,.no-print,br,ul,li {
		display:none !important;
	}
	body {
		margin:0mm;
		/* Atur margin badan ke nol atau sesuai kebutuhan */
	}
	.exclude-from-print {
		display:none !important;
	}
}
#loading {
	display:none;
	position:fixed;
	top:50%;
	left:50%;
	transform:translate(-50%,-50%);
	background-color:rgba(255,255,255,0.8);
	padding:20px;
	border:1px solid #ccc;
	box-shadow:0 0 10px rgba(0,0,0,0.2);
	z-index:999;
}
#loading-spinner {
	border:8px solid #f3f3f3;
	border-top:8px solid #3498db;
	border-radius:50%;
	width:40px;
	height:40px;
	animation:spin 1s linear infinite;
	margin:0 auto;
}
@keyframes spin {
	0% {
		transform:rotate(0deg);
	}
	100% {
		transform: rotate(360deg);
	}
}
</style>
</head>
<body>
  
<div class="container">
	<div class="row">
		<div class="col-md-6">
			<!-- Kolom kiri untuk form input -->
			<br>
			<h3>Generate Seritifikat</h3>
			<div class="form-group">
				<label for="Name">Nama Lengkap (Tanpa Gelar)*</label>
				<input type="text" class="form-control" id="name" placeholder="Masukkan Nama Lengkap Tanpa Gelar" required></div>
			<div class="form-group">
				<label for="Number">Nomor Sertifikat (Auto)</label>
				<input type="text" class="form-control" id="number" readonly></div>
			<button onclick="saveData()">Simpan</button>
			<button id="download-btn">Download</button>
			<button id="print-btn">Print</button>
			<br>
			<br>
			<h4>Cara Menggunakan:</h4>
			<ul>
				<li>
					Masukkan Nama Lengkap <i>(Tanpa Gelar)</i>
				</li>
				<li>
					Tekan <b>Simpan</b>
				</li>
				<li>
					<b>Nomor Sertifikat</b> akan otomatis muncul
				</li>
				<li>
					Silahkan <b>Download</b> atau <b>Print</b>
				</li>
			</ul>
		</div>
		<div class="col-md-6">
			<!-- Kolom kanan untuk tampilan sertifikat -->
			<br>
			<h3>Sertifikat</h3>
			<div style="border: 1px solid #ddd; height: auto; padding: 10px;">
				<canvas id="canvas" height="1754" width="2480"></canvas>
			</div>
			<br></div>
	</div>
</div>
<div id="popup" class="popup">
	<span class="close" onclick="closePopup()">&times;</span>
	<p id="popup-message"></p>
</div>
<div id="loading" style="display: none;">
	<div id="loading-spinner"></div>
	 Loading...
</div>
<div class="clearfix"></div>

<script>

// Menyimpan Data  
function saveData() {
    var nameInput = document.getElementById('name').value;
    // Memeriksa apakah input nama tidak kosong
    if (nameInput.trim() === '') {
        // Menampilkan pesan error jika input nama kosong
        alert('Nama Lengkap Wajib Di Isi');
        return; // Menghentikan proses penyimpanan jika input nama kosong
    }
    // Memeriksa apakah input nama mengandung titik (.) atau koma (,)
    if (nameInput.includes('.') || nameInput.includes(',')) {
        // Menampilkan pesan error jika input nama mengandung titik atau koma
        alert('Nama Lengkap tidak boleh mengandung titik (.) atau koma (,)');
        return; // Menghentikan proses penyimpanan jika input nama mengandung titik atau koma
    }
    // Menampilkan loading selama proses penyimpanan
    document.getElementById('loading').style.display = 'block';
    // Memanggil fungsi updateData pada Google Apps Script
    google.script.run.withSuccessHandler(function (message) {
        // Mengatur atribut readonly setelah berhasil menyimpan
        document.getElementById('name').readOnly = true;
        // Setelah menyimpan, ambil nomor dan nama untuk digambar di kanvas
        google.script.run.withSuccessHandler(function (data) {
            // data[0] berisi Nomor, data[1] berisi Nama
            // Mengisi otomatis formulir input Nomor dan membuatnya readonly
            document.getElementById('number').value = data[0];
            document.getElementById('number').readOnly = true;
            // Mengisi otomatis formulir input Nama dan membuatnya readonly
            document.getElementById('name').value = data[1];
            document.getElementById('name').readOnly = true;
            // Memanggil fungsi drawImage untuk menggambar di kanvas
            drawImage(data[0], data[1]);
            // Menampilkan tombol Download dan Print setelah simpan berhasil
            document.getElementById('download-btn').style.display = 'inline';
            document.getElementById('print-btn').style.display = 'inline';
            // Menyembunyikan loading setelah selesai
            document.getElementById('loading').style.display = 'none';
            // Menampilkan popup setelah simpan berhasil
            showPopup("Sukses! " + message);
        }).getLatestData();
    }).updateData(nameInput, null); // Nomor tidak perlu dikirim karena akan diisi otomatis oleh getLatestData
}


// Fungsi untuk menampilkan popup HTML
function showPopup(message) {
    document.getElementById('popup-message').innerText = message;
    document.getElementById('popup').style.display = 'block';
}


// Fungsi untuk menutup popup HTML
function closePopup() {
    document.getElementById('popup').style.display = 'none';
}

// Fungsi untuk Canvas Sertifikat
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var nameInput = document.getElementById('name');
var numberInput = document.getElementById('number');
var downloadBtn = document.getElementById('download-btn');
var printBtn = document.getElementById('print-btn');
var image = new Image();
image.crossOrigin = "anonymous";
image.src = 'https://i.imgur.com/GbxxyYP.png'; // Sesuaikan Background Sertifikat
image.onload = function () {
    drawImage();
}

// Fungsi untuk menampilkan canvas pada page
function drawImage() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
    // Menentukan lebar teks
    var nameWidth = ctx.measureText(nameInput.value).width;
    // Menambahkan teks "javabitpro2024" ke dalam teks numberInput
    var fullNumberText = 'Nomor : 0000' + numberInput.value + '/javabitpro/2024';
    var numberWidth = ctx.measureText(fullNumberText).width;
    // Menentukan posisi x agar teks tetap berada di tengah
    var nameXPosition = (canvas.width - nameWidth) / 2;
    var numberXPosition = (canvas.width - numberWidth) / 2;
    // Mengatur properti textBaseline dan textAlign
    ctx.textBaseline = 'middle';  // Membuat teks berada di tengah vertikal
    ctx.textAlign = 'center';      // Membuat teks berada di tengah horisontal
    
    ctx.font = 'bold 150px monotype corsiva'; //Ukuran dan Jenis Font Name
    ctx.fillStyle = '#70e'; //Warna Font Name
    ctx.fillText(nameInput.value, nameXPosition + nameWidth / 2, 770); // 770 Adalah jarak posisi teks dari atas, semakin besar angka, posisi teks semakin ke bawah
    ctx.font = 'bold italic 60px Courier New'; //Ukuran dan Jenis Font Number
    ctx.fillStyle = '#000000'; //Warna Font Number
    ctx.fillText(fullNumberText, numberXPosition + numberWidth / 2, 520); // 550 Adalah jarak posisi teks dari atas, semakin besar angka, posisi teks semakin ke bawah
} nameInput.addEventListener('input', function () { drawImage(); }); numberInput.addEventListener('input', function () { drawImage(); }); // Fungsi untuk Download downloadBtn.addEventListener('click', function () { // Buat canvas baru dengan dimensi sesuai dengan kebutuhan var downloadCanvas = document.createElement('canvas'); downloadCanvas.width = 2480; downloadCanvas.height = 1754; var downloadCtx = downloadCanvas.getContext('2d'); // Gambar elemen ke dalam canvas unduhan downloadCtx.drawImage(image, 0, 0, downloadCanvas.width, downloadCanvas.height); // Menentukan lebar teks var nameWidth = downloadCtx.measureText(nameInput.value).width; // Menambahkan teks "javabitpro2024" ke dalam teks numberInput var fullNumberText = 'Nomor : 0000' + numberInput.value + '/javabitpro/2024'; var numberWidth = downloadCtx.measureText(fullNumberText).width; // Menentukan posisi x agar teks tetap berada di tengah var nameXPosition = (downloadCanvas.width - nameWidth) / 2; var numberXPosition = (downloadCanvas.width - numberWidth) / 2; downloadCtx.font = 'bold 150px monotype corsiva'; //Ukuran dan Jenis Font Name downloadCtx.fillStyle = '#70e'; //Warna Font Name // Mengatur properti textBaseline dan textAlign downloadCtx.textBaseline = 'middle'; // Membuat teks berada di tengah vertikal downloadCtx.textAlign = 'center'; // Membuat teks berada di tengah horisontal downloadCtx.fillText(nameInput.value, nameXPosition + nameWidth / 2, 770); // 770 Adalah jarak posisi teks dari atas, semakin besar angka, posisi teks semakin ke bawah
// Mengganti ukuran font untuk numberInput (jika perlu) downloadCtx.font = 'bold italic 60px Courier New'; //Ukuran dan Jenis Font Number downloadCtx.fillStyle = '#000000'; //Warna Font Number downloadCtx.fillText(fullNumberText, numberXPosition + numberWidth / 2, 520); // 550 Adalah jarak posisi teks dari atas, semakin besar angka, posisi teks semakin ke bawah
// Unduh gambar dari canvas unduhan var link = document.createElement('a'); link.href = downloadCanvas.toDataURL('image/jpeg', 1.0); link.download = 'Certificate - ' + nameInput.value + '-' + numberInput.value + '-javabitpro2024'; link.click(); }); // Fungsi untuk Print printBtn.addEventListener('click', function () { // Draw the image before printing drawImage(); // Use window.print() directly window.print(); }); </script> <!-- Menggunakan Bootstrap JS dan Popper.js (untuk dropdown, tooltip, dan popover) --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.1/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> </body> </html>


7. Copy dan pastekan script di bawah ini ke Visit.html

Masukkan Password Untuk Melihat Script (Password sama dengan di atas)

<div class="visit-content no-print">
<link href="https://raw.githack.com/javabitpro/css/main/javabitprocssloginjp70.css" rel="stylesheet">
	<div class="fab-container2 .no-print">

  </div>
	<div class="fab-container .no-print">
		<div class="fab fab-icon-holder .no-print">
			
		</div>
		<ul class="fab-options">
			<li>
				<span class="fab-label">Youtube</span>
				<div class="fab-icon-holder">
					<a target="_blank" href="https://www.youtube.com/watch?v=s9jDQXGsnDU&list=PLDeNeiwBHjwYg7_gz2vDA1D6QfBiMgIj6&index=70"><i class="fa-brands fa-youtube"></i></i></a>
				</div>
			</li>
			<li style="margin-bottom: 10px;">
				<span class="fab-label">Website</span>
				<div class="fab-icon-holder">
					<a target="_blank" href="https://s.id/javabitpro"><i class="fa-solid fa-globe"></i></a>
				</div>
			</li>			
		</ul>
	</div>
  </div>


8. Klik ikon Save.


9. Klik tombol Terapkan/Deploy lalu pilih Deployment baru/New deployment.


10. Pastikan jenisnya adalah Aplikasi web, hak aksesnya adalah Siapa saja/Anyone lalu pilih Terapkan/Deploy.


11. Klik atau salin URL yang sudah di Deploy.


SELESAI !!!







Previous Post Next Post

Promo