Domino 附件的三種上傳法:Notes client、傳統 web form、XPages

Domino 附件的三種上傳法:Notes client、傳統 web form、XPages

在 Notes client 附一個檔案有多容易?打開一份文件、把檔案拖進一個富文本欄位,放手,就好了。容易到你不會覺得那是一個「功能」。

但同一個需求換個場景就沒那麼理所當然了。老闆說「這張表單也要能在瀏覽器上傳檔案」,或者你正在用 XPages 重寫這個應用——這時候「怎麼讓使用者上傳檔案」不是一個答案,是三個:client 一種、傳統 web form 一種、XPages 又一種。

好消息是,這三條路最後都通到同一個地方。搞懂那個「同一個地方」,三種情境就串起來了。


重點摘要

  • 三種前端、同一個儲存:不管使用者從 client、web form 還是 XPages 上傳,檔案最後都變成文件某個富文本欄位上的一個附件(在 LotusScript 裡就是一個 NotesEmbeddedObject)。
  • Client:富文本欄位天生就收附件,拖進去或用選單附加即可,不必寫程式。
  • 傳統 web form:用一個內嵌元素——File Upload ControlCreate - Embedded Element - File Upload Control),這是 web 專用的控制項。
  • XPages:用 xp:fileUpload 上傳、搭 xp:fileDownload 顯示與下載,兩者都綁到同一個富文本欄位
  • 後端程式共用:因為都落在富文本欄位,撈檔、抽取到磁碟、刪除的 LotusScript 三種情境完全一樣——站上 LotusScript 處理附件那篇已經走過。

共同底層:附件是富文本欄位上的一個 embedded object

先把「同一個地方」講清楚,後面三種情境才好對照。

在 Domino 裡,一個附件不是散在文件某處的裸檔,而是掛在某個富文本欄位上的一個 NotesEmbeddedObject——官方對這個類別的定義涵蓋三種東西:「An embedded object, An object link, A file attachment.」附件是其中一種(TypeEMBED_ATTACHMENT)。它的資料跟富文本內容分開存放,但邏輯上就掛在那個欄位下。

這也是為什麼你在瀏覽器能用一條 URL 把附件抓出來——Domino 用 $File 這個元素名對外服務它:

http://Host/Database/View/Document/$File/Filename?OpenElement

記住這個模型:上傳的前端有三種,但終點都是「某個富文本欄位上的一個附件」。所以下面三節講的其實是同一件事的三個入口。

Notes client:富文本欄位,拖進去就好

client 這一路沒什麼好教的,這正是重點——富文本欄位天生就收附件。使用者在編輯模式把檔案拖進富文本欄位、或用選單附加,檔案就掛上去了,不必你寫一行程式。這就是開頭說的「容易到不像功能」。

要用程式做(例如自動附一個產生好的報表),才會用到 NotesRichTextItem.EmbedObject

Dim rt As NotesRichTextItem
Set rt = doc.GetFirstItem("Body")
Call rt.EmbedObject(EMBED_ATTACHMENT, "", "C:\reports\Q3.pdf") ' EMBED_ATTACHMENT = 1454
Call doc.Save(True, False)

EmbedObject 官方一句話:「Attaches the file you specify to a rich text item.」第一參數用 EMBED_ATTACHMENT(值 1454)、第二個 class$ 附檔時傳空字串、第三個是要附的檔名。附上去之後怎麼列、怎麼抽取、怎麼刪,站上 LotusScript 處理附件那篇講得很完整,這裡不重複。

傳統 web 的 Notes form:File Upload Control

把同一張表單搬上瀏覽器,就不能靠「拖進富文本欄位」了——瀏覽器沒有那個互動。Domino 對傳統 web form 提供的是一個內嵌元素File Upload Control

兩個前提(官方明列):這個控制項只在 web 有效、Notes client 不支援(官方:「The file upload control is not supported in Notes」),而且伺服器管理員要先設好一個暫存目錄,否則附件不會隨文件存下來。

官方在 Designer 裡的步驟是五步:

  1. 開啟要加上傳控制項的那張表單。
  2. 把游標移到要放上傳框的位置。
  3. Create - Embedded Element - File Upload Control——從主選單建立這個內嵌元素。
  4. 選取控制項、右鍵開 File Upload Control Properties 屬性框。
  5. Hide 頁勾選 “Hide paragraph from Notes® R4.6 or later”——既然它只在 web 用,順手對 Notes client 隱藏。

Domino Designer 的「建立 → 嵌入元件 → 檔案上傳控制」選單,對應步驟 3

放好之後,Web 使用者在編輯模式下就能打路徑檔名、或按 browse 鈕挑檔上傳;送出後檔案成為這份文件的附件(跟 client 同一個模型)。

放好後,File Upload Control 在 web 表單上的樣子——「檔案上傳:」標籤配一個「檔案上載」按鈕

上傳之後要在伺服器端處理(驗證、改名、搬去別的欄位、通知),就掛一個 WebQuerySave agent,用跟 client 完全一樣的後端 API——doc.HasEmbeddeddoc.GetAttachment(檔名)、富文本欄位的 EmbeddedObjectsExtractFile——處理它。至於怎麼讓使用者把附件下載回去,用的是一條 $File 的 URL——這條很常用、也常有人記不清楚,下面單獨拆一節講。

XPages:xp:fileUpload 搭 xp:fileDownload

XPages 把上傳與下載拆成兩個成對使用的核心控制項,而且——這是關鍵——兩個都綁到文件的同一個富文本欄位

  • xp:fileUpload:官方定義「Uploads a file from the local file system.」它的 value 要「binds a control to a data element or other value which must be of type rich text」——也就是綁一個富文本欄位。
  • xp:fileDownload:「Downloads a file to the local file system.」綁同一個富文本欄位,把已附的檔案列出來讓使用者點下載;rows 控制最多顯示幾列、allowDelete 決定使用者能不能刪附件。

典型寫法就是把兩個控制項放在同一個 XPage、value 都指向同一份文件資料源的同一個富文本欄位:

<xp:fileUpload id="fileUpload1" value="#{document1.body}" />
<xp:fileDownload id="fileDownload1" value="#{document1.body}"
rows="30" allowDelete="true" />

使用者選檔、儲存文件時,xp:fileUpload 把檔案附進 body 這個富文本欄位;xp:fileDownload 則從同一個欄位把清單顯示出來、可下載、(開了 allowDelete 時)可刪。上傳與下載綁同一欄位,才會是同一批附件——這是 XPages 這一路最容易接錯的地方。

取回附件:$File 的下載 URL

三種前端上傳最後都存成同一種附件,所以「怎麼把它下載回來」也有一條通用答案:直接用一條 URL 指到那個附件。格式是:

http://Host/Database/View/Document/$File/Filename?OpenElement

官方的實例長這樣:

http://www.lotus-10.com/lproducts.nsf/By+Part+Number/SN156/$File/spec.txt?OpenElement

一段一段拆:

  • Host:server 位址(www.lotus-10.com)。
  • Database:NSF 檔名或路徑(lproducts.nsf)。
  • View:一個 view 的名字,用來定位文件(By+Part+Number;名字裡的空白在 URL 用 +)。
  • Document:在那個 view 裡指到文件的 key(實例是 SN156;實務上也常直接用文件的 UNID)。
  • $File:固定的標記,告訴 Domino「我要的是附件」。
  • Filename:附件的檔名(spec.txt)。
  • ?OpenElement:命令,叫 Domino 把這個元素吐出來。

一個很重要、但容易被忽略的提醒:官方自己都說,這種 URL「makes it impractical to create these URLs manually」——手刻很容易出錯,實務上是用程式組出來、不是叫使用者去背。三種情境怎麼拿到這條 URL:

  • XPages:不必自己組——xp:fileDownload 會幫每個附件把下載連結產好,使用者點檔名就下載。
  • 傳統 web/LotusScript:自己用文件的資訊把這條 URL 組出來(view + 文件 key/UNID + 檔名),放進頁面或計算欄位給使用者點。
  • Notes client:client 裡雙擊附件就開啟/另存,用不到這條 URL——它是給「用瀏覽器抓」的情境。

同一份附件不管從哪種前端上傳,這條 URL 都抓得到——因為終點都是同一個富文本欄位上的附件。

三種情境一張表

上傳機制綁定對象刪除後端處理
Notes client富文本欄位(拖放/選單附加)富文本欄位client 直接刪共用(7/07 篇
傳統 web formFile Upload Control(內嵌元素,web 專用)附到文件WebQuerySave / URL共用
XPagesxp:fileUpload富文本欄位(valuexp:fileDownloadallowDelete共用

三欄的「上傳機制」各不相同,但最右欄一樣——因為終點都是同一個富文本欄位上的附件。

同類別在其他語言

Java 端對應 RichTextItemEmbeddedObject(同一個「附件是富文本上的 embedded object」模型,方法名對得起來);XPages/SSJS 這一側不是用某個 class,而是用上面那兩個控制項(xp:fileUploadxp:fileDownload)綁富文本欄位來做。

小結

「怎麼讓使用者上傳檔案」在 Domino 有三個入口:client 的富文本欄位(天生就會、最容易)、傳統 web form 的 File Upload Control(web 專用內嵌元素)、XPages 的 xp:fileUploadxp:fileDownload(綁同一個富文本欄位)。前端三種寫法,終點是同一個——文件某個富文本欄位上的附件。也因此,附上去之後撈它、抽取它、刪它的 LotusScript,三種情境共用一套;那一套的細節在 LotusScript 處理附件。想更底層地理解富文本欄位本身,回 NotesRichTextItem 入門

參考來源

← 回到文章列表