【GAS】複製貼上讓試算表變身成網頁表格 秀爆你的客戶朋友!
直接把整個試算表連結發給別人除了要載入很久且會出現一堆不需要的按鍵,整個畫面很醜很沒有質感。而且如果你把其他隱私的資料也放在裡面,都會被一次看光光。那我們就來幫試算表包個糖衣吧
當你要分享表格給其他人看時,使用 Google 試算表把連結貼給別人是一個簡單快速的方法。除了可以套各種公式,修改資料會馬上同步,也可以開設權限讓其他人一起編輯。
罷特如果只是要給別人看資料比如說客戶名單、訂單資訊、直接把整個試算表連結發給別人除了要載入很久且會出現一堆不需要的按鍵,整個畫面很醜很沒有質感。而且如果你把其他隱私的資料也放在裡面,都會被一次看光光。
怎麼辦?幫它抹上一層糖衣!
我們來做一個超簡單的小網頁讓它自己去表格抓你要的資料來顯示。我們會寫一些程式 (HTML,CSS,Js)不過如果你不會也沒關系 w 只要跟著步驟複製貼上就可以了。今天我要來幫我的畫家朋友薩波來做一個網站讓他的委託人可以查看他畫圖的進度,還要讓電腦排序讓已經完成的委託排在下面。
薩波委託進度
開發者:毛哥EM(我) 類型:網站 網址:毛哥EM的基地
架一個網站!
你可以使用任何一個可以給你存放網站代碼的地方,比如說Github。
我從Codepen上找到了一個很好看的表格模板來做修改。它在螢幕尺寸太窄的時候會用不同的版面來顯示,保持使用者體驗。你也可以找其他的模板或者是自己建立一個。
See the Pen Responsive Tables using LI by Faiz Ahmed (@faaezahmd) on CodePen.
我在網站上增加了一點文字、顏色 (CSS)、超連結 (<a>
)、還有圖片、縮圖。以及簡單的出場動畫 (animate.css)來炫技。
1<!doctype html>
2<head>
3
4 <meta charset="utf-8" />
5
6
7 <title>薩波進度查詢表</title>
8
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10
11
12 <link
13 href="https://Edit-Mr.github.io/code/sabooo/thumbnail.png"
14 rel="icon"
15 type="image/x-icon"
16 />
17
18 <link
19 rel="stylesheet"
20 type="text/css"
21 href="https://Edit-Mr.github.io/css/Animate.css"
22 media="screen"
23 />
24
25
26 <meta name="theme-color" content="orange" />
27
28 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
29
30
31 <style>
32 @import url(https://fonts.googleapis.com/earlyaccess/cwtexyen.css);
33
34 body {
35 font-family: "Arial","cwTeXYen","微軟正黑體";
36 background-color: #fee5bd;
37 }
38
39 .container {
40 max-width: 1000px;
41 margin-left: auto;
42 margin-right: auto;
43 padding-left: 10px;
44 padding-right: 10px;
45 font-size: 25px;
46 }
47
48 h2 {
49 font-size: 23px;
50 margin: 0;
51 text-align: center;
52 font-weight: 150;
53 color: #e69137;
54 animation: fadeIn;
55 animation-duration: 1.5s;
56 animate-delay: 0.9s;
57 }
58
59 h1 {
60 font-size: 35px;
61 margin: 20px 0 0 0;
62 text-align: center;
63 size: 30px;
64 color: #351c75;
65 animation: zoomIn;
66 animation-duration: 1s;
67 }
68
69 li {
70 border-radius: 3px;
71 padding: 25px 30px;
72 display: flex;
73 justify-content: space-between;
74 margin-bottom: 25px;
75 }
76
77 .responsive-table .table-header,
78 .table-note {
79 background-color: #f9a756;
80 font-size: 30px;
81 margin-top: 0px;
82 padding: 25px 30px 25px 30px;
83 animation: slideInUp;
84 animation-duration: 1.5s;
85 }
86
87 .table-note {
88 font-size: 20px;
89 display: none;
90 }
91
92 .responsive-table {
93 margin: 0;
94 padding: 0;
95 }
96
97 .responsive-table .table-row {
98 background-color: #fff;
99 box-shadow: 0px 0px 9px 0px rgba(0, 0, 0, 0.1);
100 animation: backInLeft;
101 animation-duration: 1.5s;
102 }
103 .table-row{}
104 .responsive-table .col-1 {
105 flex-basis: 25%;
106 }
107
108 .responsive-table .col-2 {
109 flex-basis: 30%;
110 }
111
112 .responsive-table .col-3 {
113 flex-basis: 30%;
114 }
115
116 .responsive-table .col-4 {
117 flex-basis: 15%;
118 }
119
120 @media all and (max-width: 767px) {
121 .responsive-table .table-header {
122 display: none;
123 }
124
125 .table-note {
126 display: block;
127 }
128
129 .responsive-table li {
130 display: block;
131 }
132
133 .responsive-table .col {
134 flex-basis: 100%;
135 }
136
137 .responsive-table .col {
138 display: flex;
139 padding: 10px 0;
140 }
141
142 .responsive-table .col:before {
143 color: #6c7a89;
144 padding-right: 10px;
145 content: attr(data-label);
146 flex-basis: 50%;
147 text-align: right;
148 }
149 }
150
151 .header {
152 width: 150px;
153 display: block;
154 margin: auto;
155 animation: slideInUp;
156 animation-duration: 1.5s;
157 }
158
159 .finished {
160 color: green;
161 }
162
163 p,
164 a {
165 text-align: center;
166 font-size: 15px;
167 color: #6c7a89;
168 text-decoration: none;
169 animation: fadeIn;
170 animation-duration: 1.5s;
171 }
172
173 </style>
174</head>
175
176<body>
177
178 <div class="container">
179
180 <h1>薩波 2022 委託與贈圖表</h1>
181
182 <h2>這些不代表畫的順序 會跳著畫</h2>
183 <img src="header.png" class="header" />
184 <li class="table-note">
185 如果要一次看完整表格請切換到電腦版網頁喔
186 </li>
187
188 <ul class="responsive-table">
189
190 <li class="table-header">
191
192 <div class="col col-1">委託人姓名</div>
193
194 <div class="col col-2">委託項目</div>
195
196 <div class="col col-3">付款狀態</div>
197
198 <div class="col col-4">進度狀態</div>
199
200 </li>
201 資料載入中
202 </ul>
203 <p>
204 <a href=""></a> · Facebook<a href="https://instagram.com/"
205 >Instagram</a
206 ><br />Made by <a href="https://github.com/Edit-Mr">Edit Mr.</a
207 > with❤
208 </p>
209
210 </div>
211</body>
後端 GAS! GAS!
好了前端做好了接下來我們來建另一個網站讓剛才那個網站來這裡讀取資料。為了方便起見我們在給資料的時候直接給一個做好的表格讓網站貼上。
我們先看一下試算表。在這裡我們可以看到每一行資料有 5 項,其中我希望第 5 項的資料可以放在付款狀態後面。現在請你先請你複製這個試算表的 ID,也就是網址https://docs.google.com/spreadsheets/d/
和/
之間那一串 (如1fjX-prGu0hfb65LCQkrktWa-JavvjSz7tWMmYWAb7RA
)。等一下會用到。
我們會使用 GAS(Google Apps Script) 來建立網頁應用程式來讀取表格資料。
Google Apps Script
開發者:Google 類型:免費網站(可付費升級) 網址:script.google.com
請建立一個新的專案並貼上以下內容。記得貼上 Google Sheet 那段 ID,並修改自己要的範圍,程式碼裡有詳細的註解。原理是讀取一行行的資料並轉成 HTML 表格,其中如果狀態是完成的加上一個 class 讓顏色變綠色。在排序方面我是把完成的和未完成的分成兩個陣列(清單)儲存,在把完成的接在未完成的後面合併。
小叮嚀 為避免程式碼站太多空間,可能會部分隱藏。請記得展開或直接複製。
1function doGet() {
2 var spreadsheet = SpreadsheetApp.openById(
3 "1U-Q2XXXXXXXRsrh-QYCXXXXXXXXXQmGQ"
4 ); // Sheet id
5 var sheet = spreadsheet.getSheets()[0];
6 var rowLength = sheet.getLastRow();
7 var columnLength = sheet.getLastColumn();
8 var data = sheet.getRange(3, 1, rowLength, columnLength).getValues();
9 var dataExport = [
10 '<li class="table-header"><div class="col col-1">委託人姓名</div><div class="col col-2"++>委託項目</div><div class="col col-3">付款狀態</div><div class="col col-4">進度狀態</div></li>'
11 ];
12 var stat,
13 ed = [];
14 // 一個個加入 json
15 for (i in data) {
16 if (data[i][0] != "") {
17 if (data[i][3] == "完成") {
18 ed.push(
19 '<li class="table-row"><div class="col col-1" data-label="委託人姓名">' +
20 data[i][0] +
21 '</div><div class="col col-2" data-label="委託項目">' +
22 data[i][1] +
23 '</div><div class="col col-3" data-label="付款狀態">' +
24 data[i][2] +
25 " " +
26 data[i][4] +
27 '</div><div class="col col-4 finished" data-label="進度狀態">' +
28 data[i][3] +
29 "</div></li>"
30 );
31 } else {
32 dataExport.push(
33 '<li class="table-row"><div class="col col-1" data-label="委託人姓名">' +
34 data[i][0] +
35 '</div><div class="col col-2" data-label="委託項目">' +
36 data[i][1] +
37 '</div><div class="col col-3" data-label="付款狀態">' +
38 data[i][2] +
39 " " +
40 data[i][4] +
41 '</div><div class="col col-4" data-label="進度狀態">' +
42 data[i][3] +
43 "</div></li>"
44 );
45 }
46 }
47 }
48 dataExport = dataExport.concat(ed);
49 // 回傳 JSON
50 console.log(dataExport.join(""));
51 return ContentService.createTextOutput(dataExport.join(""));
52}
為什麼要分兩個陣列?不要讓未完成的直接插入到最前面?
我們可以用push()
將資料插入到最後面,也可以用unshift()
插入到最前面。但是如果用這個方式未完成的清單順序會整個便相反
如順序1234567
排序後不會變124589367
,而是985421367
。
你可以根據自己的需求決定排法
做好了之後點擊執行▶️,你會需要授予你的程式讀取資料的權限。因為你寫的程式沒有被 Google 驗證過所以會顯示不安全,但我相信你不會把你的帳號搞爆,對吧
接下來我們要部署它,讓它成為一個網站來讓我們抓。這裡選擇網頁應用程式,所有人都以你的身份讀取。按下部署就可以囉
這裡我們把部署的網址複製起來。如果要做修改除了按儲存之外要記得重新部署成新版本才會更新喔
接下來我們回到 Github 的網頁讓他來讀這個表格
等等,不是做好表格網頁了,直接讓它顯示就好了啊幹嘛那麼麻煩? 可以當然是可以,姑且不論網址有多長多醜,如果使用 Google Apps Script 建設的網站會出現橫幅很醜的一個警告,而且他超長讓你的版面整個跑掉。為了更好的使用者體驗既然都做了就做到底吧!
前端 讀取資料
最後一步了!我們回到程式碼的 head 裡面,加入 jQuery 這個套件讓我們可以少寫幾行
然後我們修改一下body
。程式讀到表格之後會用表格取代class
裡面的所有內容。我已在這裡可以寫一些表格讀取到之前會顯示的訊息比如說「資料讀取中...」之類的。
最後在我們在</body>
前面貼上以下的 JavaScript 來讀取並顯示表格。記得把網址換成剛剛表格資料的網址喔~
1<script>
2 //請把下面按這串改成剛才的網址
3 let requestURL =
4 "https://script.google.com/macros/s/AKfycbxq942U9fZK5tR6Vi1OZkr5Hq0Bv_qPSm1rOOYFFZUS_vyrTu60QuW7xmU-d09UpI1XLQ/exec";
5 let request = new XMLHttpRequest();
6 request.open("GET", requestURL);
7 request.responseType = "text";
8 request.send();
9 request.onload = function () {
10 console.log("載入成功");
11 $("p").addClass("animate_animated", "animate_fadeOut"); //動畫
12 $(".responsive-table").html(request.response); //用表格取代.responsive-table
13 };
14</script>
最終程式碼
最終的程式碼如下,有沒有超有成就感?
顯示網站
1<!doctype html>
2<head>
3
4 <meta charset="utf-8" />
5
6
7 <title>薩波進度查詢表</title>
8
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10
11
12 <link
13 href="https://Edit-Mr.github.io/code/sabooo/thumbnail.png"
14 rel="icon"
15 type="image/x-icon"
16 />
17
18 <link
19 rel="stylesheet"
20 type="text/css"
21 href="https://Edit-Mr.github.io/css/Animate.css"
22 media="screen"
23 />
24
25
26 <meta name="theme-color" content="orange" />
27
28 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
29
30
31 <style>
32 @import url(https://fonts.googleapis.com/earlyaccess/cwtexyen.css);
33
34 body {
35 font-family: "Arial","cwTeXYen","微軟正黑體";
36 background-color: #fee5bd;
37 }
38
39 .container {
40 max-width: 1000px;
41 margin-left: auto;
42 margin-right: auto;
43 padding-left: 10px;
44 padding-right: 10px;
45 font-size: 25px;
46 }
47
48 h2 {
49 font-size: 23px;
50 margin: 0;
51 text-align: center;
52 font-weight: 150;
53 color: #e69137;
54 animation: fadeIn;
55 animation-duration: 1.5s;
56 animate-delay: 0.9s;
57 }
58
59 h1 {
60 font-size: 35px;
61 margin: 20px 0 0 0;
62 text-align: center;
63 size: 30px;
64 color: #351c75;
65 animation: zoomIn;
66 animation-duration: 1s;
67 }
68
69 li {
70 border-radius: 3px;
71 padding: 25px 30px;
72 display: flex;
73 justify-content: space-between;
74 margin-bottom: 25px;
75 }
76
77 .responsive-table .table-header,
78 .table-note {
79 background-color: #f9a756;
80 font-size: 30px;
81 margin-top: 0px;
82 padding: 25px 30px 25px 30px;
83 animation: slideInUp;
84 animation-duration: 1.5s;
85 }
86
87 .table-note {
88 font-size: 20px;
89 display: none;
90 }
91
92 .responsive-table {
93 margin: 0;
94 padding: 0;
95 }
96
97 .responsive-table .table-row {
98 background-color: #fff;
99 box-shadow: 0px 0px 9px 0px rgba(0, 0, 0, 0.1);
100 animation: backInLeft;
101 animation-duration: 1.5s;
102 }
103 .table-row{}
104 .responsive-table .col-1 {
105 flex-basis: 25%;
106 }
107
108 .responsive-table .col-2 {
109 flex-basis: 30%;
110 }
111
112 .responsive-table .col-3 {
113 flex-basis: 30%;
114 }
115
116 .responsive-table .col-4 {
117 flex-basis: 15%;
118 }
119
120 @media all and (max-width: 767px) {
121 .responsive-table .table-header {
122 display: none;
123 }
124
125 .table-note {
126 display: block;
127 }
128
129 .responsive-table li {
130 display: block;
131 }
132
133 .responsive-table .col {
134 flex-basis: 100%;
135 }
136
137 .responsive-table .col {
138 display: flex;
139 padding: 10px 0;
140 }
141
142 .responsive-table .col:before {
143 color: #6c7a89;
144 padding-right: 10px;
145 content: attr(data-label);
146 flex-basis: 50%;
147 text-align: right;
148 }
149 }
150
151 .header {
152 width: 150px;
153 display: block;
154 margin: auto;
155 animation: slideInUp;
156 animation-duration: 1.5s;
157 }
158
159 .finished {
160 color: green;
161 }
162
163 p,
164 a {
165 text-align: center;
166 font-size: 15px;
167 color: #6c7a89;
168 text-decoration: none;
169 animation: fadeIn;
170 animation-duration: 1.5s;
171 }
172
173 </style>
174</head>
175
176<body>
177
178 <div class="container">
179
180 <h1>薩波 2022 委託與贈圖表</h1>
181
182 <h2>這些不代表畫的順序 會跳著畫</h2>
183 <img src="header.png" class="header" />
184 <li class="table-note">
185 如果要一次看完整表格請切換到電腦版網頁喔
186 </li>
187
188 <ul class="responsive-table">
189
190 <li class="table-header">
191
192 <div class="col col-1">委託人姓名</div>
193
194 <div class="col col-2">委託項目</div>
195
196 <div class="col col-3">付款狀態</div>
197
198 <div class="col col-4">進度狀態</div>
199
200 </li>
201 資料載入中
202 </ul>
203
204 <p>
205 <a href="https://www.facebook.com/Sabo9335">薩波 FB</a> · <a
206 href="https://instagram.com/sabooo_9335?igshid=YmMyMTA2M2Y="
207 >薩波 IG</a
208 > · <a href="https://discord.gg/ve9ERWVEPR">橘子牌太空船</a
209 ><br />Made by <a href="https://github.com/Edit-Mr">EDM</a> with❤
210 </p>
211
212 </div>
213
214 <script>
215 //請把下面按這串改成剛才的網址
216 let requestURL = "https://script.google.com/macros/s/xxxxxxxx/exec";
217 let request = new XMLHttpRequest();
218 request.open("GET", requestURL);
219 request.responseType = "text";
220 request.send();
221 request.onload = function () {
222 console.log("載入成功");
223 $("p").addClass("animate_animated", "animate_fadeOut"); //動畫
224 $(".responsive-table").html(request.response); //用表格取代.responsive-table
225 };
226 </script>
227</body>
表格資料網站
1function doGet() {
2 var spreadsheet = SpreadsheetApp.openById(
3 "1U-Q2t9RI6Uce787RASQIRsrh-QYCvhCgn_UyOnrQmGQ"
4 ); // Sheet id
5 var sheet = spreadsheet.getSheets()[0];
6 var rowLength = sheet.getLastRow();
7 var columnLength = sheet.getLastColumn();
8 var data = sheet.getRange(3, 1, rowLength, columnLength).getValues();
9 var dataExport = [
10 '<li class="table-header"><div class="col col-1">委託人姓名</div><div class="col col-2"++>委託項目</div><div class="col col-3">付款狀態</div><div class="col col-4">進度狀態</div></li>'
11 ];
12 var stat,
13 ed = [];
14 // 一個個加入 json
15 for (i in data) {
16 if (data[i][0] != "") {
17 if (data[i][3] == "完成") {
18 ed.push(
19 '<li class="table-row"><div class="col col-1" data-label="委託人姓名">' +
20 data[i][0] +
21 '</div><div class="col col-2" data-label="委託項目">' +
22 data[i][1] +
23 '</div><div class="col col-3" data-label="付款狀態">' +
24 data[i][2] +
25 " " +
26 data[i][4] +
27 '</div><div class="col col-4 finished" data-label="進度狀態">' +
28 data[i][3] +
29 "</div></li>"
30 );
31 } else {
32 dataExport.push(
33 '<li class="table-row"><div class="col col-1" data-label="委託人姓名">' +
34 data[i][0] +
35 '</div><div class="col col-2" data-label="委託項目">' +
36 data[i][1] +
37 '</div><div class="col col-3" data-label="付款狀態">' +
38 data[i][2] +
39 " " +
40 data[i][4] +
41 '</div><div class="col col-4" data-label="進度狀態">' +
42 data[i][3] +
43 "</div></li>"
44 );
45 }
46 }
47 }
48 dataExport = dataExport.concat(ed);
49 // 回傳 JSON
50 console.log(dataExport.join(""));
51 return ContentService.createTextOutput(dataExport.join(""));
52}