Google sheet Apps script | QR code Scaner – Quét thông tin mã QR và lưu thông tin trên google sheet
Giaoan.link chia sẻ tiếp đến các bạn về Google sheet Apps script “QR code Scaner – Quét thông tin mã QR và lưu thông tin trên google sheet”. Project này sẽ xây dựng dạng webapp có thể truy cập trên máy tính bảng và điện thoại. Webapp này có thể dùng camera để quét mã QR hoặc load một ảnh QR có trên máy để lấy thông tin và điền thêm thông tin sau đó gửi và lưu lại trên sheet của google.
Bạn có thể xem video hướng dẫn theo link bên dưới và code appscript để bạn tham khảo.
Các bài học về appscript khác:
- Tạo hóa đơn trên Google sheet – Gửi email đính kèm hóa đơn pdf – Quản lý url hóa đơn trên danh sách
- Google sheet Ứng dụng theo dõi đơn hàng – Danh sách sản phẩm mua, trạng thái đơn hàng
- Tip on Ms Word Hướng dẫn tạo ngắt trang, xóa ngắt trang đơn lẽ hoặc toàn bộ ngắt trang trên file doc
- Google sheet | Generate QR Codes – Mã hóa nội dung Cell – Thêm hình ở giữa mã QR code
- Google sheet App Script | Tạo custom menu – Xóa tất cả dòng Rỗng trên vùng dữ liệu Nhanh chống
- Google Script Web | From upload file – Kiểm tra trùng lặp – Ghi đè hoặc Tạo phiên bản mới cho file
- Google Script Web | Trang Tìm kiếm nhiều điều kiên riêng lẽ hoặc hết hợp – Print, Xuất file PDF
- Hướng dẫn kiểm tra Bàn phím, Tháo và thay bàn phím mới cho Dell Inspirion 15 3000 series
- Google sheet webapp | Quản lý bán hàng – Chức nằn trả góp, In thông tin
- Ổ C đầy Di chuyển dữ liệu ZALO sang Ổ D hoặc ổ khác một cách dễ dàng Không lo zalo báo đầy ổ đĩa
Mã file “code.gs”
/**
* This web app uses the html5-qrcode library from GitHub: https://github.com/mebjas/html5-qrcode.
* The html5-qrcode library is used to scan QR codes from the user's webcam.
*/
//Constants
const DATASHEET = "Data";
function doGet() {
let template = HtmlService.createTemplateFromFile('Index');
let html = template.evaluate().setTitle('QR Code Scanner');
html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
html.addMetaTag('viewport', 'width=device-width, initial-scale=1');
return html;
}
function processForm(formObject) {
const ss = SpreadsheetApp.getActive();
const dataSheet = ss.getSheetByName(DATASHEET);
dataSheet.appendRow([
new Date().toLocaleString(),
formObject.product_name,
formObject.product_category,
formObject.quantity,
formObject.price,
formObject.productCode
]);
}
/**
* INCLUDE HTML PARTS, EG. JAVASCRIPT, CSS, OTHER HTML FILES
*/
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
Mã file “Index.html”
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<?!= include('CSS'); ?>
<!-- See CSS.html file -->
</head>
<body class="bg-black text-light">
<nav class="navbar sticky-top navbar-dark bg-primary">
<div class="container-fluid">
<a class="navbar-brand mx-auto" href="#"><span><i class="bi bi-qr-code-scan"></i></span> Quét mã QR code </a>
</div>
</nav>
<div class="container" style="border: solid 2px #aafe7d; border-radius: 10px" >
<?!= include('Form'); ?>
<!-- See Form.html file -->
</div>
<?!= include('JavaScript'); ?>
<!-- See JavaScript.html file -->
<?!= include('QrReaderJS'); ?>
<!-- See QrReaderJS.html file -->
</body>
</html>
Mã file “CSS.html”
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<style>
#qr-reader {
/* Default width for all devices */
width: 100%;
box-sizing: border-box;
/* Include padding and border in width calculation */
}
@media only screen and (max-width: 600px) {
#qr-reader {
width: 100%;
}
}
</style>
Mã file “Form.html”
<div id="qr-reader" class="mt-4" style="position: relative; padding: 0px; border: none;"></div>
<div id="qr-reader-results"></div>
<br>
<form id="InventoryForm" onsubmit="handleFormSubmit(this)">
<div class="mb-3 input-group">
<span class="input-group-text bg-primary text-white"><i class="bi bi-link"></i></span>
<input type="text" class="form-control" id="productCode" name="productCode" placeholder="Scan QR/Bar Code" readonly>
</div>
<div class="mb-3 input-group">
<span class="input-group-text bg-primary text-white"><i class="bi bi-box-fill"></i></span>
<input type="text" class="form-control" id="productName" name="product_name" placeholder="Tên sản phẩm">
</div>
<div class="mb-3 input-group">
<!-- <label for="productCategory" class="form-label">Product Category:</label> -->
<span class="input-group-text bg-primary text-white"><i class="bi bi-tags-fill"></i></span>
<select class="form-select" id="productCategory" name="product_category">
<option disabled selected>Chọn Danh Mục</option>
<option value="electronics">Đồ điện tử</option>
<option value="clothing">Thời trang</option>
<option value="books">Sách</option>
<option value="other">Loại khác</option>
</select>
</div>
<div class="mb-3 input-group">
<span class="input-group-text bg-primary text-white"><i class="bi bi-123"></i></span>
<input type="number" class="form-control" id="quantity" name="quantity" placeholder="Số lượng">
</div>
<div class="mb-3 input-group">
<span class="input-group-text bg-primary text-white"><i class="bi bi-currency-dollar"></i></span>
<input type="number" step="0.01" class="form-control" id="price" name="price" placeholder="Giá thành">
</div>
<button type="submit" class="btn btn-warning mb-3 w-100 fw-bold">Submit</button>
</form>
Mã file “JavaScript.html”
<script>
window.addEventListener("load", functionInit, true);
//Initialize functions onload
function functionInit(){
preventFormSubmit();
};
// Prevent forms default behaviour (Prevent reloading the page)
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
/**
* The handleFormSubmit() function passes the formObject to the processForm
* function in the Code.gs file
*/
function handleFormSubmit(formObject) {
// Get the QR data from the div
google.script.run.processForm(formObject);
const resultContainer = document.getElementById('qr-reader-results');
resultContainer.innerHTML = '';
document.getElementById("InventoryForm").reset();
}
</script>
Mã file “QrReaderJS.html”
<!--
This code uses the html5-qrcode library from GitHub: https://github.com/mebjas/html5-qrcode
Example Link: https://gist.github.com/mebjas/729c5397506a879ec704075c8a5284e8
-->
<script src="https://unpkg.com/html5-qrcode@2.3.8/html5-qrcode.min.js" type="text/javascript"></script>
<script>
function docReady(fn) {
// see if DOM is already available
if (document.readyState === "complete" || document.readyState === "interactive") {
// call on next available tick
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
docReady(function() {
var resultContainer = document.getElementById('qr-reader-results');
var lastResult, countResults = 0;
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", { fps: 10, qrbox: 250 });
function onScanSuccess(decodedText, decodedResult) {
if (decodedText !== lastResult) {
++countResults;
lastResult = decodedText;
console.log(`Scan result = ${decodedText}`, decodedResult);
resultContainer.innerHTML += `<div class="p-3 mb-2 bg-success text-white">[${countResults}] - ${decodedText}</div>`;
//Assign the scanned code to productCode field
const productCode = document.getElementById("productCode");
productCode.value = decodedText;
}
}
// Optional callback for error, can be ignored.
function onScanError(qrCodeError) {
// This callback would be called in case of qr code scan error or setup error.
// You can avoid this callback completely, as it can be very verbose in nature.
}
html5QrcodeScanner.render(onScanSuccess, onScanError);
});
</script>