HTML 轉 PDF 之 wkhtmltopdf 工具精講
術語定義
文件物件
“文件物件”是指PDF文件中的文件物件,共有三種類型的“文件物件”,他們分別是“頁面物件”,“封面物件”和“目錄物件”。
頁面物件
“頁面物件”是指以頁面的形式在PDF文件中呈現的物件,這個是相對於“封面物件”和“目錄物件”來講的。此類物件會成為PDF文件中內容。
封面物件
“封面物件”是指以封面的形式在PDF文件中呈現的物件。這類物件會成為PDF文件中的封面。
目錄物件
“目錄物件”是以目錄的形式在PDF文件中呈現的物件,又叫“TOC物件”。這類物件會成為PDF文件中的目錄。
大綱
“大綱”是指閱讀PDF文件時的書籤導航。
外鏈
“外鏈”是指所有在這個頁面中且不指向它自身頁面中錨點的超連結。
內鏈
“內鏈”是指在這個頁面中且指向的目標頁面是這個頁面本身中的一個錨點的超連結。
命令格式
wkhtmltopdf [GLOBAL OPTION]... [OBJECT]... <output file>
上述程式碼就是 wkhtmltopdf 的命令列格式,看似簡單,其實在 [GLOBAL OPTION]
和 [OBJECT]
中還別有洞天。預知詳情,且聽我慢慢道來。
文件物件簡介
wkhtmltopdf 能夠把多個“物件”合併生成一個pdf文件,這些“物件”可以是“頁面物件”、“封面物件”、或是“目錄物件”。這些物件在pdf文件中的順序可以通過命令列引數來指定。命令列引數包括兩部分,一種是針對某一特定“物件”的命令列引數,另一種是全域性的命令列引數。並且全域性的命令列引數只能放在全域性引數區([GLOBAL OPTION])中指定。
頁面物件簡介
“頁面物件”作用是用來把一個網頁作為內容輸出到PDF文件中。
(page)? <input url/file name> [PAGE OPTION]...
“頁面物件”的引數可以放在“全域性引數域([GLOBAL OPTIONS])”和“頁面引數域([PAGE OPTIONS])”。程式會根據實際情況在所有引數中找到合適的引數應用到頁面、頁首和頁尾。
封面物件簡介
“封面物件”用來把一個網頁作為封面輸出到PDF文件中,輸出的頁面不會在TOC中出現,並且不會包含頁首和頁尾。
cover <input url/file name> [PAGE OPTION]...
所有能夠在“頁面物件”中使用的引數都可以用到“封面物件”
目錄物件簡介
“目錄物件”的作用是輸出一個目錄到PDF檔案中。
toc [TOC OPTION]...
所有能夠在“頁面物件”中使用的引數都可以用到“TOC物件”,並且還有許多的針對“TOC物件”的引數可以應用到“TOC物件”中。目錄是通過 XSLT 生成的,這就意味著它可以被定義成任何你想看到的樣子。你可以通過命令列引數 --dump-default-toc-xsl
輸出預設的 XSLT 文件,通過 --dump-outline
命令列引數 可指定以XML格式輸出當前處理文件的目錄到指定檔案。更多詳細內容請檢視後面介紹的 目錄物件引數
命令引數
命令引數包含五部分,分別是“全域性引數”,“大綱引數選項”,“頁面物件引數”,“頁首和頁尾引數選項”和“目錄物件引數”。
全域性引數
--collate 當輸出多個副本時進行校驗(這是預設設定)
--no-collate 當輸出多個副本時不進行校驗
--cookie-jar <path> 從提供的JAR檔案中讀寫cookie資料
--copies <number> 設定輸出副本的數量(預設主1),其實為1就夠了
-d, --dpi <dpi> 指定一個要解析度(這在 X11 系統中並沒有什麼卵用)
-H, --extended-help 相對 -h 引數,顯示更詳細的說明文件
-g, --grayscale 指定以灰度圖生成PDF文件。佔用的空間更小
-h, --help 顯示幫助資訊
--htmldoc 輸出程式的html幫助文件
--image-dpi <integer> 當頁面中有內嵌的圖片時,
會下載此命令列引數指定尺寸的圖片(預設值是 600)
--image-quality <interger> 當使用 jpeg 演算法壓縮圖片時使用這個引數指定的質量(預設為 94)
--license 輸出授權資訊並退出
-l, --lowquality 生成低質量的 PDF/PS ,能夠很好的節約最終生成文件所佔儲存空間
--manpage 輸出程式的手冊頁
-B, --margin-bottom <unitreal> 設定頁面的 底邊距
-L, --margin-left <unitreal> 設定頁面的 左邊距 (預設是 10mm)
-R, --margin-right <unitreal> 設定頁面的 右邊距 (預設是 10mm)
-T, --margin-top <unitreal> 設定頁面的 上邊距
-O, --orientation <orientation> 設定為“風景(Landscape)”或“肖像(Portrait)”模式,
預設是肖像模組(Portrait)
--page-height <unitreal> 頁面高度
-s, --page-size <Size> 設定頁面的尺寸,如:A4,Letter等,預設是:A4
--page-width <unitreal> 頁面寬度
--no-pdf-compression 不對PDF物件使用丟失少量資訊的壓縮演算法,不建議使用些引數,
因為生成的PDF檔案會非常大。
-q, --quiet 靜態模式,不在標準輸出中列印任何資訊
--read-args-from-stdin 從標準輸入中讀取命令列引數,後續會有針對此指令的詳細介紹,
請參見 **從標準輸入獲取引數**
--readme 輸出程式的 readme 文件
--title <text> 生成的PDF文件的標題,如果不指定則使用第一個文件的標題
-V, --version 輸出版本資訊後退出
上述程式碼區是所有全域性引數及註釋,下面簡單說一下個別引數的意義及用法。
--copies N
N 是一個正整數。
這個選項可以先不用關心了,因為你這輩子可能都用不到。他的作用是在生成的PDF文件中,把內容重複輸出 N 份。也就是說,你將得到一個PDF文件,這個文件中的大小、內容量都將是不使用此引數時的 N 倍。然而重複的內容對你來說並沒有什麼卵用。
如果不使用 --copies
引數,那麼 --collate
和 --no-collate
引數就不用瞭解了,因為他們只在 --copies
引數中的 N 大於 1 時才有意義。
-g, --grayscale
這個引數非常有用,使用這個引數可以有效壓縮生成的PDF所佔用的儲存空間。當然這個壓縮是要付出一定代價的,那就是最終生成的PDF文件將是灰度的,沒有任何色彩。如果你能接受灰度PDF文件,並不影響實際使用,那就請使用這個引數吧。生成的PDF文件越大,使用此引數獲得的驚喜就越大。
-l, --lowquality
這個引數與 -g
引數有異曲同工之妙, -l
引數也會大大壓縮PDF文件所佔用的儲存空間。只是它是通過降低PDF文件的質量來完成這一任務的。這個引數也值得推薦,你最好先嚐試一下,看看使用此引數後生成的PDF文件與不使用此引數的區別再做決定。我可以告訴你的是,在純文字的情況下他們的差別不大,此引數只是降低了PDF文件的質量,看上去是糙了一些,但不會影響閱讀。如果你是一個追求感官享受,或是你生成的PDF文件中有大量圖片,那就不要使用此引數了。
--no-pdf-compression
這個引數強烈建議不要使用,最好這輩子都不要去了解他的好,因為對於你來說肯定用不到。它的作用就是在輸出PDF文件時,不使用任何的壓縮。這將會導致輸出的PDF文件特別的大,質量是無損的,但是對於人類來說從感觀上根本察覺不到壓縮前後的質量變化的。如果你的感觀超乎於常人,壓縮之後的體驗對你來說無法接受,那我收回前面的話,你就盡情使用此引數吧。
-q, --quiet
使用這個引數後,你將得到一個乾淨的命令列輸出,就連程式處理的進度和狀態都沒有。這個引數會抑制所有命令列輸出,在程式的工作過程中,你看不到任何輸出。建議不會使用此引數,因為程式輸出一些進度和狀態資訊還是非常有用的。萬一程式工作到某處死了呢(嘿嘿),在 -q
模式下你是無法分辨是否程式死掉了的。
大綱引數選項
--dump-default-toc-xsl 輸出預設的 TOC xsl 樣式表到標準輸出
--dump-outline <file> 輸出“大綱”到指定的檔案(檔案內容為xml)
--outline 在生成的PDF文件中輸出“大綱”(這是預設設定)
--no-outline 不在pdf文件中輸出大綱
--outline-depth <level> 設定生成大綱的深度(預設為 4)
大綱引數中唯一需要特別說一下的是 --outline-depth
,其他引數預設就好了。
何為大綱
大綱
如上圖所示,其實我更喜歡稱之為目錄或導航。大綱是根據你HTML中的標題(Hn標籤)自動生成的。
--outline-depth
--outline-depth
用來指定生成的大綱的深度。預設值為 4。你可以指定一個大一些的數字,以保證所有在HTML中指定的H標籤都能在大綱中生成對應的項,方便閱讀時快速跳轉。
當指定了 --no-outline
引數時, 將不會輸出大綱到PDF文件,所以再指定 --outline-depth
也就沒有意義了。
頁面物件引數
--allow <path> 指定載入HTML中相對路徑檔案的目錄(可重複使用此引數指定多個
目錄),這個引數會在後面進行更詳細的講解
--background 輸出頁面背景到PDF文件(這是預設設定)
--no-background 不輸出頁面背景到PDF文件
--cache-dir <path> 網頁的快取目錄
--checkbox-checked-svg <path> 使用指定的SVG檔案渲染選中的複選框
--checkbox-svg <path> 使用指定的SVG檔案渲染未選中的篩選框
--cookie <name> <value> 設定訪問網頁時的cookie,value 需要進行url編碼
(可重複使用此引數指定多個cookie)
--custom-header <name> <value> 設定訪問網頁時的HTTP頭(可重複使用此引數指定多個HTTP頭)
--custom-header-propagation 為每個要載入的資源新增由 --custom-header 指定的HTTP頭
--no-custom-header-propagation 不為每個要載入的資源新增由 --custom-header 指定的HTTP頭
--debug-javascript 顯示javascript除錯輸出的資訊
--no-debug-javascript 不顯示javascript除錯輸出的資訊(這是預設設定)
--default-header 新增一個預設的“頭”,在頁面的左頭顯示頁面的名字,
在頁面的右頭顯示頁碼,這相對於進行了如下設定:
--header-left='[webpage]'
--header-right='[page]/[toPage]'
--top 2cm
--header-line
--encoding <encoding> 為輸入的文字設定預設的編碼方式
--disable-external-links 禁止頁面中的外鏈生成超連結
--enable-external-links 允許頁面中的外鏈生成超連結(這是預設設定)
--disable-forms 不轉換HTML表單為PDF表單(這是預設設定)
--enable-forms 轉換HTML表單為PDF表單
--images 載入圖片並輸出到PDF文件(這是預設設定)
--no-images 在生成的PDF文件中過濾掉圖片
--disable-internal-links 禁止頁面中的內鏈生成超連結
--enable-internal-links 允許頁面中的內鏈生成超連線(這是預設設定)
-n, --disable-javascript 禁止WEB頁面執行 javascript
--enable-javascript 允許WEB頁面執行 javascript(這是預設設定)
--javascript-delay <msec> 延遲一定的毫秒等待javascript 執行完成(預設值是200)
--load-error-handling <handler> 指定當頁面載入失敗後的動作,可以指定為:abort(中止)、
ignore(忽略)、skip(跳過);(預設值是:abort)
--load-media-error-handling <handler> 指定當媒體檔案載入失敗後的動作,可以指定為:
abort(中止)、ignore(忽略)、skip(跳過);
(預設值是:ignore)
--disable-local-file-access 不允許一個本地檔案載入其他的本地檔案,使用命令列引數
`--allow` 指定的目錄除外。
--enable-local-file-access 允許本地檔案載入其他的本地檔案(這是預設設定)
--minimum-font-size <int> 設定最小的字號,除非必要不推薦使用該引數
--exclude-from-outline 拒絕載入當前頁面到PDF文件的目錄和大綱中
--include-in-outline 載入當前頁面到PDF文件的目錄和大綱中(這是預設設定)
--page-offset <offset> 設定頁碼的起始值(預設值為0)
--password <password> HTTP身份認證的密碼
--disable-plugins 禁止使用外掛(這是預設設定)
--enable-plugins 允許使用外掛,但外掛可能並不工作
--post <name> <value> 新增一個POST欄位,可以重複使用該引數新增多個POST欄位。
--post-file <name> <value> 新增一個POST檔案,可以重複使用該引數新增多個檔案。
--print-media-type 用顯示媒體型別代替螢幕
--no-print-media-type 不用顯示媒體型別代替螢幕
-p, --proxy <proxy> 使用代理
--radiobutton-checked-svg <path> 使用指定的SVG檔案渲染選中的單選框
--radiobutton-svg <path> 使用指定的SVG檔案渲染未選中的單選框
--run-sript <js> 頁面載入完成後執行一個附加的JS檔案,可以重複使用此引數指定
多個要在頁面載入完成後要執行的JS檔案。
--disable-smart-shrinking 不使用智慧收縮策略
--enable-smart-shrinking 使用智慧收縮策略(這是預設設定)
--stop-slow-scripts 停止執行緩慢的javascript程式碼(這是預設設定)
--no-stop-slow-scripts 不停止執行緩慢的javascript程式碼
--disable-toc-back-links 禁止從標題連結到目錄(這是預設設定)
--enable-toc-back-links 允許從標題連結到目錄
--user-style-sheet <url> 設定一個在每個頁面都載入的使用者自定義樣式表
--username <username> HTTP身誰的使用者名稱
--viewport-size <> 設定視窗大小,需要你自定義滾動條或css屬性來自適應視窗大小。
--window-status <windowStatus> Wait until window.status is equal to
this string before rendering page
--zoom <float> 設定轉換成PDF時頁面的縮放比例(預設為1)
上面程式碼段中只是對所有 頁面物件引數 做了個大概的說明,下面針對個別主要引數做更詳細的講解。
--allow
這個引數只在“頁面物件”是一個檔案時有效,在“頁面物件”是一個url時此引數無效。
這個引數的作用是為HTML頁面中使用相對路徑引用的檔案指定一個載入檔案的基目錄。也就是說HTML檔案中所有以相對路徑指定的檔案都會從 --allow
引數指定的目錄進行載入。其實在HTML中指定 base
標籤可以達到同樣的目的。如果兩者(--allow
引數和base
標籤)都沒有指定,則使用當前處理的HTML檔案所在的目錄作為基目錄載入當前處理的HTML中相對路徑指定的檔案。
--background AND --no-background
這兩個引數是一對,用來指定是否在生成的PDF中應用網頁的背景,預設 --background
引數是開啟的,也就是說預設生成的PDF文件中是帶有HTML頁面的背景圖片或背景色的。如果開啟 --no-backgroupd
引數,則生成的PDF文件中不會有HTML頁面中的背景圖片和背景色。
--debug-javascript ADN --no-debug-javascript
這兩個引數用來指定是否在標準輸出中輸出javascript的除錯資訊,預設 --no-debug-javasript
引數是開啟的,也就是說預設不會輸出javascript的除錯資訊。下圖是開啟 --debug-javascript
引數的演示。
--debug-javascript
--disable-external-links AND --enable-external-links
這兩個引數是用來設定在頁面中的外鏈是否以超連結的形式出現在PDF文件中。關於“外鏈”的定義請移架 術語定義 。預設 --enable-external-links
引數被開啟,所以預設情況是頁面中的外鏈是以超連結的形式出現的PDF文件中的,點選可以開啟指定的網頁。
--exclude-from-outline AND --include-in-outline
這兩個引數用來設定當前頁面物件是否包含到目錄和大綱中。
預設情況下 --include-in-outline
引數是開啟的。也就是說預設情況下生成的PDF文件目錄和大綱中是包含當前頁面的,如果你不想讓當前頁面加到目錄和大綱中可以開啟 --exclude-from-outline
引數。
--post AND --post-file
當目標頁面需要接受POST表單才能正確得到響應時,可以用這兩個引數。這兩個引數都是可以重複使用的。
還有一個應用場景是,用於自動化的WEB應用測試中。可以得到PDF文件作為測試報告。
--post-file
也可以用於自動批量上傳檔案的場景。
--run-sript
當需要對頁面進行一定的預處理後再生成PDF文件的場景,使用該引數再合適不過了。這個引數可以重複使用指定多個需要在頁面載入完成後執行的JS程式碼。你可以在這些JS中對頁面的結構和內容進處理,JS執行完成後才會把對應的頁面生成PDF文件。
--disable-internal-links AND --enable-internal-links
這兩個引數是用來設定在頁面中的內鏈是否以超連結的形式出現在PDF文件中。關於“內鏈”的定義請移架 術語定義 。預設 --enable-internal-links
引數被開啟,所以預設情況是頁面中的內鏈是以超連結的形式出現的PDF文件中的,點選在當前PDF中跳轉到指定錨點。
--enable-toc-back-links AND --disable-toc-back-links
這組引數用來設定,是否在PDF內容中的H標籤處生成超連結。生成的超連結點選後會跳轉到目錄和大綱中該H標籤對應的錨點位置。預設情況下 --disable-toc-back-links
引數被開啟,不會在PDF文件的H標籤處生成超連結。
如果你需要在閱讀PDF文件的內容時快速回到目錄,你可以開啟 --enable-toc-back-links
引數。
--user-style-sheet
這個引數用來載入一個使用者自定義的樣式表,用來改變HTML頁面原有的樣式。需要高度自定義頁面新式的同學可以嘗試使用這個引數達到目的。
頁首和頁尾引數選項
--footer-center <text> 在頁尾的居中部分顯示頁尾文字 <text>
--footer-font-name <name> 設定頁尾的字型 (預設為 Arial)
--footer-font-size <size> 設定頁尾的字型大小 (預設為 12)
--footer-html <url> 新增一個html作為頁尾
--footer-left <text> 在頁尾的居左部分顯示頁尾文字 <text>
--footer-line 在頁尾上方顯示一條直線分隔正文
--no-footer-line 不使用直線分隔頁尾與正文(這是預設設定)
--footer-right <text> 在頁尾的居右部分顯示頁尾文字 <text>
--footer-spacing <real> 頁尾與正文之間的距離(預設為零)
--header-center <text> 在頁首的居中部分顯示頁首文字 <text>
--header-font-name <name> 設定頁首的字型 (預設為 Arial)
--header-font-size <size> 設定頁首的字型大小 (預設為 12)
--header-html <url> 新增一個html作為頁首
--header-left <text> 在頁首的居左部分顯示頁首文字 <text>
--header-line 在頁首下方顯示一條直線分隔正文
--no-header-line 不使用直線分隔頁首與正文(這是預設設定)
--header-right <text> 在頁首的居右部分顯示頁首文字 <text>
--header-spacing <real> 頁首與正文之間的距離(預設為零)
頁首頁尾的設定比較簡單,看上述程式碼段中的解釋已經非常明瞭,所以不再贅述。後面還有針對頁首與頁尾的其他相關介紹。
目錄物件引數
--disable-dotted-lines 在目錄中不使用虛線
--toc-header-text <text> 設定目錄的頁首文字
--toc-level-indentation <width> 第級標題在目錄中的縮排寬度(預設為1em)
--disable-toc-links 在目錄中不生成指向內容錨點的超連結
--toc-text-size-shrink <real> 在目錄中每級標題的縮放比例(預設為0.8)
--xsl-style-sheet <file> 使用自定義的 XSL 樣式表顯示目錄內容
“目錄物件”我們一般用不到,上述程式碼段中的講解也不難懂,所以不針對每一個具體引數再做詳細的講解。
關於頁面尺寸說明
你還可以使用 --page-height
和 --page-width
對頁面尺寸進行更精細的控制。
從標準輸入獲取引數
如果你需要對許多頁面進行批量的處理,並且感覺 wkhtmltopdf 開啟比較慢,你可以嘗試使用 --read-args-from-stdin
引數。
wkhtmltopdf 命令會為 --read-args-from-stdin
引數傳送過來的每一行進行一次單獨命令呼叫。也就是說此引數每讀取一行都會執行一次 wkhtmltopdf 命令。而最終執行的命令中的引數是命令列中引數與此引數讀取的標準輸入流中引數的結合。
下面的程式碼段是一個例子:
echo "http://qt-project.org/doc/qt-4.8/qapplication.html qapplication.pdf" >> cmds
echo "cover google.com http://en.wikipedia.org/wiki/Qt_(software) qt.pdf" >> cmds
wkhtmltopdf --read-args-from-stdin --book < cmds
指令一個代理
預設情況下代理資訊將讀取環境變數:proxy、all_proxy 和 http_proxy,代理選項還可以通過指定 -p
引數開啟。
使用 BNF 對代理的定義如下:
<type> := "http://" | "socks5://"
<serif> := <username> (":" <password>)? "@"
<proxy> := "None" | <type>? <serif>? <host> (":" <port>)?
如果你不熟悉 BNF 的話,下面的程式碼段中是三個例子:
http://user:[email protected]:8080
socks5://myproxyserver
None
頁首和頁尾
頁首和頁尾可以使用引數 --header-*
和 --footer-*
新增到檔案中。有些引數(如 --footer-left
)需要提供一個字串text
作為引數值。你可以在 text
中插入下述變數,他們將會被替換成對應的值。
[page] 當前正在被輸出頁面的頁碼
[frompage] 第一頁在文件中的頁碼
[topage] 最後一面在文件中的頁碼
[webpage] 當前正在被輸出頁面的URL
[section] 當前正在被輸出的章節的名字
[subsection] 當前正在被輸出的小節的名字
[date] 本地系統格式的當前日期
[isodate] ISO 8601 格式的當前日期
[time] 本地系統格式的當前時間
[title] 當前物件的標題
[doctitle] 輸出文件的標題
[sitepage] 當前正在處理的物件中當前頁面的頁碼
[sitepages] 當前正在處理的物件中的總頁數
舉一個例子來說明吧,--header-right "Page [page] of [toPage]"
, 會在頁面的右上角生成一個類似 Page x of y
的字串,其中 x
是當前頁面的頁碼, y
是當前文件最後一頁的頁碼。
頁首和頁尾也可以通過 HTML文件來提供。 同樣舉一個例子,使用命令列引數 --header-html header.html
來生成頁首,而 header.html 的內容如下:
<html><head><script>
function subst() {
var vars={};
var x=window.location.search.substring(1).split('&');
for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for (var i in x) {
var y = document.getElementsByClassName(x[i]);
for (var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script></head><body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
<tr>
<td class="section"></td>
<td style="text-align:right">
Page <span class="page"></span> of <span class="topage"></span>
</td>
</tr>
</table>
</body></html>
大綱(Outlines)
wkhtmltopdf 可以使用 --outline
命令列引數來指定在PDF就要中輸出像書本中目錄一樣的“大綱”,“大綱”是基本HTML文件中H標籤生成的,具體的大綱的層級和嘗試請移步 目錄
如果HTML文件中的H標籤等級比較多,就可以生成深層級樹形結構的“大綱”,而生成“大綱”的真實深度是通過 --outline-depth
引數來控制。
目錄
通過在命令列中新增 TOC物件 可以把一個目錄新增到生成的PDF文件中,例如下面的程式碼段:
wkhtmltopdf toc http://qt-project.org/doc/qt-4.8/qstring.html qstring.pdf
生成的目錄也是基於HTML文件的H標籤。過程是首先生成一個XML文件,然後使用XSLT轉換為HTML。
生成的 XML 文件可以通過 --dump-outline
引數檢視。
wkhtmltopdf --dump-outline toc.xml http://qt-project.org/doc/qt-4.8/qstring.html qstring.pdf
你如果想要使用自定義的XSLT文件可以通過 --xsl-style-sheet
引數指定
wkhtmltopdf toc --xsl-style-sheet my.xsl http://qt-project.org/doc/qt-4.8/qstring.html qstring.pdf
你可以使用 --dump-default-toc-xsl
引數把預設的 XSLT 文件列印到標準輸出,然後基於它建立你的自定義 XSLT 文件。
wkhtmltopdf --dump-default-toc-xsl
總結
以上就是有關 wkhtmltopdf 工具的所有內容,這些內容中的大部分是通過閱讀 wkhtmltopdf 的 -H
引數輸出的英文文件獲取的。水平有限,如有不足請指正。
作者:JSON_NULL 連結:https://www.jianshu.com/p/4d65857ffe5e/ 來源:簡書 簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。