2021/12/16

JS / 將網頁轉換成PDF

將網頁轉換成PDF的方法很多種

比較常見且最簡單的方式就是直接使用列印功能

在印表機選擇”另存成PDF”

不過我還是想嘗試能不能用JavaScript的方式來輸出

在網路找了很多教學文章

大致可以分為兩種方式

1.使用名稱為 jsPDF的函式庫

但是這個函式庫比較適合”無中生有”的方式來”產生”PDF

Demo的網頁就可以看出來,可以透過函式庫的不同方法(method)來產生PDF

然而想要將現成的網頁轉成PDF時,無論是直接使用addHTML輸出網頁內容

還是使用html2canvas,將網頁先輸出成canvas再轉換成PDF

兩種方式產生的PDF內容都會變形或者有缺漏

比較好的方式是搭配另一個函式庫 rasterizehtml 

先處理html,然後透過jsPDF輸出成canvas,再轉成PDF

 

2.利用windows物件的功能

將想要輸出的頁面寫入一個新的視窗,執行列印,在印表機選擇”另存成PDF”

或者其他PDF模擬印表機的功能

這個方式的輸出效果應該是最好,只是流程上還是會有需要手動執行

不能按一個鈕,然後直接產生PDF

也或許可能,後續可以再研究研究

 
 

需要注意的地方是不管是方法1.還是方法2

頁面的CSS都要寫在輸出頁面的區塊內

這樣才能將CSS效果一起輸出

如果使用jsPDF的話,需要注意版本的問題

1.X版的物件宣告跟2.X版的不一樣

1.X版是   .jsPDF

2.X版則是   .jspdf.jsPDF

應該也有功能細部上的差異,但是我只是用到轉換的功能

所以沒有感覺有太大的差別

2021/12/01

App / 使用App Inventor 製作取得運動中心容留人數的APP (2024/2/24 修改)

2024/2/24 修改

1. Fetch 網址改變,如果用瀏覽器開啟會自動轉址,但是App Inventor沒有可以設定的地方(或者是我沒找到)

新的網址:https://www.tpejjsports.com.tw/index.php/zh-TW/frontend/onsitenum

2.寫出資料到index.html(可省略)的「寫出網頁資料」程序

似乎因為Android安全性的問題,檔案無法直接存在手機,但是可以寫入外部記憶卡

在模擬器測試時是沒有問題

不過我的手機沒有插卡,所以把 index.html上傳到網頁空間

VBA / 抓取網路 JSON資料 版本2

VBA / 抓取網路 JSON資料透過資料分割的分是取得JSON資料

Gg / App 從Google Spreadsheets建立查詢ISBN的AppSheet APP 版本2

提到彰化一整天對於Html的處理方式只用了javascript內建函式

2021/11/23

SoftWave / 使用PowerPoint 2019 錄製視訊旁白

之前在SoftWave / 使用OBS錄製PowerPoint簡報

使用了免費軟體OBS的錄製瀏覽器/視窗的功能來錄製簡報

後來發現在PowerPoint 2019、OFFICE365(桌機板)可以直接錄製視訊旁白

預設的功能區並沒有錄製功能,必須從自訂功能區中設定

也就是原有的旁白錄製功能,再加上視訊畫面

微軟官網的說明其實就很詳細了

跟其他軟體的最大差異是在PowerPoint錄製的視訊是跟簡報畫面分開的

在錄製過程中可以關閉預覽,只留簡報畫面

並且每一頁都可以調整視訊影像的位置,改變影像圖形、大小

也由於是直接在簡報過程中錄製內容

所以基本上不用再經過後製去頭去尾

如果有需要也是可以直接在PowerPoint裡處理

算是相對方便的錄製方式

只是要留意轉場時的影像跟聲音不會被錄進去

必須預留轉場的空檔

其他相關的應用可以參考李燕秋老師的教學影片

2021/11/18

Gg / 透過LINE Notify推播尼采名言

寫在前面《當失戀的我 遇上尼采》的心得

 

回頭來說明這個程式

可以分為兩個部分

1.將網路上的尼采名言整理放在Google試算表

2.在試算表新增App Script並連結到Line Notify

以下分別說明

1.將網路上的尼采名言整理放在Google試算表

Google關鍵字-尼采名言,就會有一大堆,雖然也不知道到底是不是尼采所言

總之挑選了一些比較有積極面向的語錄存放在試算表

2.在試算表新增App Script並連結到Line Notify

function runToLine()是啟動程式

在AppScript設置以時間為條件來進行觸發

因為不想半夜還收到訊息,所以設置在每天的7點到22點才進一步觸發主程式function NietzscheToLine()

function NietzscheToLine()是主程式

以試算表的資料筆數為範圍進行亂數取數,運用了 Math.floor(Math.random()*(max-min+1))+min 這樣的規則

取得介於1~筆數的隨機整數

為了避免前後次取道相同的數值,所以必須記錄本次取得的筆數,做為下一次數值的比較依據

將取得的數值對應試算表的資料欄位,取出儲存格內的資料

最後傳遞到sendMessage3()這個處理LINE Notify的程序

將訊息傳推播出去

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function runToLine(){
  var time =new Date();
  var runTime = time.getHours();  
  //Logger.log(time);
  
  if(runTime >=7  && runTime <=22){     // 07:00 ~ 22:00  
    NietzscheToLine();  
  }else{   
    return;  
  }
}

function NietzscheToLine() {
  // https://docs.google.com/spreadsheets/d/********************************************/
  // sheet "Nietzsche"
  var ss = SpreadsheetApp.openById("********************************************").getSheetByName("Nietzsche"); 
  var Row = ss.getLastRow();
  //Logger.log('Row- '+Row);

  var g = ss.getRange("B2").getValue();     //取得在B2儲存上一次的序號  
  //Logger.log(g);
  
  //Math.floor(Math.random()*(max-min+1))+min
  var i = Math.floor(Math.random()*(Row-1+1))+1; // 本次序號
  //Logger.log(i);
  
  while( g == i){
    i = Math.floor(Math.random()*(Row-1+1))+1; 
  }
    
  var msg = "\n" + i + "-" +ss.getRange("A" + i).getValue();
  //Logger.log(msg);

  sendMessage3(msg.toString(), "446", "1990");  
  ss.getRange("B2").setValue(i) ;  //寫出本次序號
}


function sendMessage3(message, stickerPackageId, stickerId){  
  var Token = "23rGWk1BMDeplI3G0Nue9e7dakMtLAwje0kUdGu4VrK";
  var URL = "https://notify-api.line.me/api/notify";

  var payload = 
      {
        'message' : message,
        //'imageThumbnail':'https://ih1.redbubble.net/image.1317550651.4451/flat,128x128,075,f-pad,128x128,f8f8f8.jpg',
        //'imageFullsize':'https://ih1.redbubble.net/image.1317550651.4451/flat,128x128,075,f-pad,128x128,f8f8f8.jpg'
        'stickerPackageId': stickerPackageId,
        'stickerId': stickerId
      };
  
  var header =
      {
        'Content-Type':'application/x-www-form-urlencoded',
        'Authorization' : 'Bearer ' + Token        
      }
  
  var options =
      {
        'method'  : 'post',
        'payload' : payload,
        'headers' : header
      }; 

  var response = UrlFetchApp.fetch(URL, options);
  //Logger.log("response"+response);
}