IBM Lotus Symphony 開發人員教程: 構建一個簡單的文件工作流外掛
當許多人想到 IBM Lotus Symphony 時,他們理所當然地認為這是一組提高辦公效率的編輯器,但是它的功能實際上遠不只如此。因為 Symphony 基於 OpenOffice.org 技術和 Eclipse/Lotus Expeditor 富客戶機平臺,所以它是一個可擴充套件的產品。Lotus 合作伙伴可以利用這種靈活性作為 Symphony 使用者介面的自然擴充套件新增新的特性,增強基本產品的功能。正如在這個實驗中將看到的,也可以提供編輯功能之外的與業務相關的功能。無論是增強現有的基本編輯特性,還是新增與業務相關的功能,實現的方法是相同的:開發一個外掛並“連線到”Symphony 中。這個實驗的目的是,演示如何使用外掛以各種方式擴充套件辦公套件的功能。
在這個實驗中,我們要建立一個簡單的文件工作流外掛。文件工作流應用程式可以對文件庫中的辦公文件應用簡單的工作流。在開啟一個文件時,這個文件在 Lotus Symphony 視窗中開啟並在應用程式中顯示工作流資訊。可以修改工作流資訊並儲存在文件中。文件用一個特殊的模板構建並儲存在本地。
下圖顯示 Document Workflow 外掛的使用者介面。
圖 1. Document Workflow 外掛的使用者介面
Document Workflow 外掛演示關鍵功能,比如如何執行以下任務:
- 宣告一個擴充套件,在邊架(左邊皮膚)中新增應用程式
- 用 Lotus Symphony API 開啟文件
- 訪問和修改文件的內容
我們將從頭建立這個外掛並使用預先編寫的程式碼片段,從而加快手工資料輸入過程的速度。這個實驗的目的是,幫助那些熟悉 Java 程式設計的開發人員通過開發外掛擴充套件 Symphony。瞭解 Eclipse 和 OpenOffice.org UNO 程式設計知識會有幫助,但不是必需的。
為了建立 Document Workflow 應用程式,需要執行以下步驟:
- 檢查 Eclipse 開發環境
- 從 Eclipse 開發環境執行 Lotus Symphony
- 為 Document Workflow 應用程式建立 Eclipse 外掛
- 構建一個簡單的 Eclipse 外掛,為 Lotus Symphony 提供邊架
- 用 Eclipse 的 Standard Widget Toolkit(SWT)建立應用程式的使用者介面
- 操作庫中的文件
- 開啟庫中的文件
- 訪問並修改文件
- 在裝載文件時讀取工作流資訊
- 修改工作流資訊
- 使用 c:\Eclipse32 目錄中的 Symphony_techfest 快捷方式。選擇 Window > Open Perspective > Other...,然後選擇 Plug-in Development 並單擊 OK,切換到外掛開發環境。
- 單擊工具欄中的 Run 按鈕,Lotus Symphony 應該會啟動。如果禁用了 Run 選項,那麼選擇 Run > Run... 開啟執行時配置對話方塊。選擇 Eclipse Application > Symphony,然後單擊 Run 按鈕。如果詢問是否希望清空執行時工作空間,那麼選擇 No。
注意:開啟 Symphony 之後,關閉歡迎頁面。
- 當 Lotus Symphony 視窗開啟時,單擊 File > New > Document,會看到以下視窗:
這是標準的 Symphony 文件編輯器。在下一節中,將在開發環境中新增一個 Eclipse 外掛並測試它的效果。在此之前,選擇 File > Exit 關閉 Symphony 的執行時例項。
為 Document Workflow 應用程式建立 Eclipse 外掛
- 啟動 Eclipse 開發環境。
- 單擊 File > New > Project。
- 選擇“Plug-in Project”並單擊“Next”。
- 在 Project name 框中輸入 com.ibm.productivity.tools.sample.DocumentWorkflow。其他選項保持預設設定。
- 單擊 Next。
- 在 Plug-in Name 框中輸入一個描述性的名稱,比如 Document Workflow sample。其他選項保持預設設定。
- 單擊 Finish。
下面的表格列出 Document Workflow 使用的一些外掛依賴項(外掛名是簡寫的):
外掛 | 說明 |
---|---|
org.eclipse.core.runtime,org.eclipse.ui | Eclipse 核心外掛 |
com.ibm.productivity.tools.ui.views com.ibm.productivity.tools.core |
Lotus Symphony API 外掛 |
com.ibm.rcp.ui, com.ibm.rcp.jfaceex, com.ibm.rcp. swtex |
RCP 使用者介面 API |
按照以下步驟新增外掛依賴項:
- 單擊 Document Workflow 外掛清單的 Dependencies 附籤。
- 單擊 Add。
- 新增以下外掛:
- com.ibm.productivity.tools.ui.views
- com.ibm.productivity.tools.core
- com.ibm.rcp.ui
- com.ibm.rcp.jfaceex
- com.ibm.rcp.swtex
結果:螢幕應該像下圖這樣(外掛的次序並不重要)。
注意:新增這些外掛依賴項會在定義這個外掛的 MANIFEST.MF 檔案中新增以下程式碼。切換到 Plug-in Manifest Editor 的 MANIFEST.MF 附籤就可以看到這個檔案的內容:
RequireBundle: org.eclipse.ui, org.eclipse.core.runtime, com.ibm.productivity.tools.ui.views, com.ibm.productivity.tools.core, com.ibm.rcp.jfaceex, com.ibm.rcp.ui, com.ibm.rcp.swtex |
- 單擊 Extensions 附籤。
- 單擊 Add。
- 新增以下擴充套件 com.ibm.rcp.ui.shelfViews。
- 單擊 Finish。
- 右鍵單擊新增的擴充套件並選擇 New > shelfView。
選擇這個選單項將在擴充套件宣告中新增一個 shelfview 元素。選擇新新增的元素,Extension Element Details 應該已經更新了,顯示元素的屬性。按照下圖填寫屬性。
星號(*)表示必需的屬性。這裡最重要的屬性是 class 屬性;這個屬性表示實現 shelfview 的行為的 Java 類(也就是說,這個類定義邊架區域將包含什麼內容,它如何響應使用者事件,等等)。這個文件中使用的 id 是 com .ibm.productivity.tools.sample.documentworkflow.ShelfView。可以複製並貼上它。
- 單擊 plugin.xml 附籤。
- 把以下程式碼複製並貼上到 plugin.xml 中:
要點:com.ibm.rcp.ui.shelfViews 擴充套件中
標記的 view 屬性必需與 org.eclipse.ui.views 擴充套件中 標記的 id 屬性匹配。也就是說,邊架內容由擴充套件的 / 對定義。 上面這個步驟在平臺上提供了一個新的 Eclipse ViewPart。可以用 Manifest Editor 建立自己的外掛擴充套件,也可以直接在 plugin.xml 中指定擴充套件。
- 在 Package Explorer 中右鍵單擊包“com.ibm.productivity.tools.sample.documentworkflow”,選擇 New > Class。
- 輸入以下類資訊,可以單擊“Browse…”按鈕搜尋超類 org.eclipse.ui.part.ViewPart。
結果:在 com.ibm.productivity.tools.samples.documentworkflow 包中建立一個新的 Eclipse ViewPart,ShelfView。
- 檢查外掛。
在執行應用程式之前,先看一下 plugin.xml 和剛才建立的類:
plugin.xml 的內容如下:
在 Package Explorer 中雙擊 ShelfView.java,ShelfView.java 的內容如下:
package com.ibm.productivity.tools.sample.documentworkflow; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; public class ShelfView extends ViewPart{ public void createPartControl(Composite arg0){ //TODO Auto-generated method stub } public void setFocus(){ //TODO Auto-generated method stub } }
- 單擊工具欄中的“Run”按鈕。
- Lotus Symphony 將會啟動;單擊 File > New > Document,螢幕應該像下圖這樣:
提示:如果沒有顯示剛才建立的檢視,那麼檢查控制檯中“org.eclipse.ui.PartInitException: Could not create view: XXX”這樣的訊息,並確認 XXX 是檢視 id。com.ibm.rcp.ui.shelfViews 擴充套件中
標記的 view 屬性必需與 org.eclipse.ui.views 擴充套件中 標記的 id 屬性匹配。 祝賀您!您已經在 Lotus Symphony 邊架中為您的應用程式留出了空間。接下來,我們將開啟、訪問並修改文件庫中的文件。
在開始使用 Lotus Symphony API 之前,我們先要新增 Document Workflow 應用程式所需的所有變數和方法,還有並非 Lotus Symphony 專用的一些 helper 方法。然後,就可以轉到與擴充套件 Lotus Symphony 相關的程式碼。在 ShelfView.java 中新增以下程式碼。
定義以下變數。把這些程式碼複製並貼上到 ShelfView.java 的開頭。
private Text ownerTxt; private Text statusTxt; private RichDocumentView selectedView = null; privateTableViewer viewer; |
注意:在貼上程式碼片段之後,使用選單項 Source > Organize Imports(Ctrl+Shift+O)新增所需的匯入語句。例如,在以上片段中,需要匯入 com.ibm .productivity.tools.ui.views.RichDocumentView 包。
要點:有幾個包定義了 TableViewer 和 Text。一定要選擇 org.eclipse.jface.viewers.TableViewer 和 org.eclipse.swt.widgets.Text。
Document Workflow 在 Lotus Symphony 的邊架上提供一個可見區域。這個區域是使用 Eclipse 的標準部件集 SWT(Standard Widget Toolkit)在 createPartControl 方法中定義的。
SWT API 用來在 Eclipse 平臺中建立使用者介面元素。複製以下程式碼並替換 ShelfView.java 中的 createPartControl 方法。
以下程式碼片段在邊架中建立一個 Document Library 組和 Workflow 組以及其他 SWT 控制元件。
public void createPartControl(Composite parent){ parent.setLayout(new RowLayout()); //Group of Document Library int y = 10; Group doclibGrp = new Group(parent, SWT.NULL); doclibGrp. setText( "Document Library"); doclibGrp.setSize(390, 72); doclibGrp.setLocation(10, y); viewer = newTableViewer(doclibGrp, SWT.MULTI |SWT.H_SCROLL |SWT.V_SCROLL); viewer.getTable( ) .setSize(120, 60); viewer.getTable().setLocation(30, y + 20); viewer.setContentProvider(new LibraryContentProvider()); viewer.setLabelProvider(new LibraryLabelProvider()); viewer.setInput(this ); hookDoubleClickAction(); //Group of user information y = 10+ doclibGrp.getBounds().height + 7; Group workflowGrp = new Group(parent, SWT.NULL); workflowGrp. setText ( "Workflow"); workflowGrp.setSize(390, 72); workflowGrp.setLocation(10, y); Label wnerLbl = new Label(workflowGrp, SWT.SHADOW_NONE |SWT.RIGHT); ownerLbl.setText ( "Owner"); ownerLbl.setSize(40, 22); ownerLbl.setLocation(10, 22); Label statusLbl = new Label(workflowGrp, SWT.SHADOW_NONE |SWT.RIGHT); statusLbl.setText( "Status"); statusLbl.setSize(40, 22); statusLbl.setLocation(10, 46); wnerTxt = new Text(workflowGrp, SWT.BORDER |SWT.LEFT); ownerTxt.setBackground(new Color(this.getSite(). getShell().getDisplay(), 255, 255, 255)); ownerTxt.setSize(80,16); ownerTxt.setLocation(100, 21); statusTxt = new Text(workflowGrp, SWT.BORDER |SWT.LEFT); statusTxt.setBackground(new Color(this.getSite().getShell().getDisplay( ) , 255, 255, 255)); statusTxt.setSize(80,16); statusTxt.setLocation(100, 46); Button commitBtn = new Button( workflowGrp, SWT.BORDER |SWT.PUSH ); commitBtn. setText ("Commit"); commitBtn.setSize(80, 20); commitBtn.setLocation(50, 67); commitBtn.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected( SelectionEvent arg0){ //TODO Auto-generated method stub } public void widgetSelected(SelectionEvent arg0){ } }); } |
注意:在貼上程式碼片段之後,使用選單項 Source > Organize Imports(Ctrl+Shift+O)新增所需的匯入語句。如果缺少方法和類,只需繼續複製並貼上以下程式碼。
要點:有幾個包定義了 Label 和 SelectionEvent。一定要選擇 SWT 包中定義的。
需要匯入以下這些包,可以檢查這個列表或者在匯入部分中複製並貼上以下程式碼。
import java.io.IOException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.part.ViewPart; import org.osgi.framework.Bundle; import com.ibm.productivity.tools.ui.views.RichDocumentView; |
SWT 是一個跨不同平臺通用的低層部件集,包括標籤、文字輸入框、按鈕等等。Eclipse 開發人員可以使用另一個稱為 JFace 的框架簡化部件程式碼,這會把“部件友好的”資料型別(比如字串)對映為“應用程式友好的”物件(比如 Clients、Documents 和相似的高階類)。例如,TableViewer 使用“helper”物件處理 Documents 等高階物件到部件需要的低階資料型別(比如字串)的對映。下面兩個類定義這些 helper 類。
需要以下方法和類;把它們複製並貼上到 ShelfView.java 的末尾。
LibraryContentProvider 提供 Document Library 中列出的文件的檔名。
class LibraryContentProvider implements IStructuredContentProvider{ public void inputChanged(Viewerv,Object oldInput, Object newInput){ } public void dispose(){ } public Object[] getElements(Object parent){ return new String[] { "Document 1", "Document 2", "Document 3" }; } } |
LibraryLabelProvider 為 Document Library 中列出的每個文件的檔名提供可見文字。
class LibraryLabelProvider extends LabelProvider implements ITableLabelProvider{ public String getColumnText(Object obj, int index){ return getText ( obj); } public Image getColumnImage(Object obj, int index){ return getImage(obj); } public Image getImage(Object obj){ return null; } } |
要點:有多個包定義了 Image。一定要選擇 SWT 包中定義的 Image。
這個方法處理 Document Library 中發生的雙擊操作。
private void hookDoubleClickAction(){ viewer.addDoubleClickListener(new IDoubleClickListener(){ public void doubleClick(DoubleClickEvent event){ ISelection selection = viewer.getSelection(); Object bj = ((IStructuredSelection)selection).getFirstElement(); String displayName = obj.toString(); String url = getDocumentURL( displayName ); } }); } |
這個方法把 Document Library 中列出的每個文件的顯示名轉換為絕對 URL。
private String getDocumentURL( String displayName) { String url =""; String res = "docs/" + displayName + ".odt"; url = getResolvedPath( res ); return url; } private String getResolvedPath(String file){ String resolvedPath = null; Bundle bundle = Platform.getBundle ("com. ibm. productivity.tools . sample. DocumentWorkflow" ); if (bundle != null){ java.net.URL bundleURL = bundle.getEntry( "/" ); if (bundleURL != null){ try{ resolvedPath = FileLocator.resolve( bundleURL ).getFile(); }catch (IOException e){ e.printStackTrace(); } } } String ret = resolvedPath+file; ret = ret.substring(1); ret = ret.replace('/', '\\'); return ret; } |
要點:有多個包定義了 IOException 和 Platform。一定要選擇 Java 和 Eclipse 包中定義的內容。
我們在本教程中使用一個虛構的文件庫,所有檔案都是本地檔案。按照以下步驟建立這個庫:
- 切換到 Windows Explorer,找到教程的目錄,比如 c:\ls 08_TechFest,右鍵單擊 docs 目錄並選擇 Copy。
- 切換到 Eclipse 環境,右鍵單擊 com.ibm.productivity.tools.sample.DocumentWorkflow 外掛並選擇 Paste。
結果:建立以下的 docs 目錄:
- 確認以上操作是正確的,單擊 File > Save All。
- 單擊工具欄中的 Run 按鈕。
結果:應用程式啟動;單擊 File > New > Document,螢幕應該與下圖相似。
找到 ShelfView.java 中的 hookDoubleClickAction 方法,在這個函式末尾新增以下程式碼行。當雙擊文件庫中的一個檔案項時,以下程式碼會自動開啟這個文件。
RichDocumentView view = RichDocumentViewFactory. openView( url, false); |
注意:在貼上程式碼片段之後,使用選單項 Source > Organize Imports(Ctrl+Shift+O)新增所需的匯入語句。需要匯入 com.ibm.productivity.tools.ui.views.RichDOcumentViewFactory 包。螢幕應該像下面這樣:
在 Eclipse 中,Eclipse 工作臺提供的選擇服務(selection service)可以高效地連結工作臺視窗中的不同部分。每個工作臺視窗有自己的選擇服務例項。這個服務會跟蹤當前啟用的部分中選擇的內容,並把選擇的更改傳播給註冊的所有監聽器。在當前部分中選擇的內容發生變化時,或者在啟用另一個部分時,會引發選擇事件。這兩種情況可以通過使用者互動或程式觸發。
每個 Lotus Symphony 檢視都註冊選擇提供器,這樣就可以監視 Lotus Symphony 中發生的選擇更改事件。
以下程式碼演示如何在 Lotus Symphony 中使用選擇提供器。請執行以下步驟:
建立 ISelectionListener 的例項
當使用者在開啟的檢視之間切換時,呼叫選擇監聽器。把程式碼複製並貼上到 ShelfView.java 中。它在執行時執行以下任務:
- 獲得選擇的 RichDocumentView。
- 獲得當前選擇的檢視的 UNO 模型。
- 用 UNO API 查詢文件中的工作流資訊。
- 更新 Document Workflow 應用程式的使用者介面。
private ISelectionListener selectionListener = new ISelectionListener() { public void selectionChanged(IWorkbenchPart arg0, ISelection arg1){ IAdaptable adaptable = ( IAdaptable ) arg1; RichDocumentViewSelection selection = ( RichDocumentViewSelection) adaptable.getAdapter(RichDocumentViewSelection.class); selectedView = selection.getView(); Object model = selectedView.getUNOModel(); XTextTablesSupplier tableSupplier = ( XTextTablesSupplier) UnoRuntime.queryInterface( XTextTablesSupplier.class, model ); XNameAccess nameAccess = tableSupplier.getTextTables(); try{ XTextTable table =( XTextTable ) UnoRuntime.queryInterface (XTextTable.class,nameAccess.getByName("Workflow")); XCell cell = table.getCellByName( "B2" ); XText text = ( XText ) UnoRuntime.queryInterface(XText.class, cell); String wner = text.getString(); cell = table.getCellByName("B3"); text = ( XText ) UnoRuntime.queryInterface(XText.class, cell); String reviewer = text.getString(); updateWorkflowInfo( owner,reviewer ); } catch (NoSuchElementException e){ //TODO Auto-generated catch block e.printStackTrace(); } catch (WrappedTargetException e){ //TODO Auto-generated catch block e.printStackTrace(); } } }; |
要點:有多個包定義了 NoSuchElementException 和 XText。一定要選擇 Sun 包(而不是 Java 包)中定義的內容。
要點:請注意以下行;它用來獲得當前文件的 UNO 文件模型。UNO 文件模型是訪問和修改文件內容的入口點。可以獲得文件中的幾乎所有物件。在這個實驗中,您將學習如何訪問文件中一個預定義的表“workflow”。
Object model = selected View.getUNOModel(); |
注意:在貼上程式碼片段之後,使用選單項 Source > Organize Imports(Ctrl+Shift+O)新增所需的匯入語句。需要匯入多個包。請對照以下程式碼檢查螢幕。
import org.eclipse.core.runtime. IAdaptable; import com.sun.star.container.NoSuchElementException; import com.sun.star.container.XNameAccess; import com.sun.star.lang.WrappedTargetException; import com.sun.star.table.XCell; import com.sun.star.text.XText; import com.sun.star.text.XTextTable; import com.sun.star.text.XTextTablesSupplier; import com.sun.star.uno.UnoRuntime; import com.ibm.productivity.tools.ui.views.RichDocumentViewSelection; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPart; updateWorkflowInfomethod The following code updates the User Interface of Document Workflow application. private void updateWorkflowInfo(String owner,String reviewer){ ownerTxt .setText (owner); statusTxt.setText (reviewer); } |
註冊選擇監聽器
為了讓選擇監聽器起作用,需要向選擇服務註冊監聽器。把以下程式碼複製並貼上到 createPartControl() 方法的末尾。
IWorkbenchWindow window = PlatformUI.getWorkbench(). getActiveWorkbenchWindow(); ISelectionService service = window.getSelectionService(); service.addSelectionListener(selectionListener); |
注意:在貼上程式碼片段之後,使用選單項 Source > Organize Imports(Ctrl+Shift+O)新增所需的匯入語句。需要匯入多個包。請對照以下程式碼檢查螢幕。
import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; |
到目前為止,已經從文件中讀取了外掛資訊。現在,學習如何用 Document Workflow 應用程式的內容修改當前的 Lotus Symphony 文件。按照以下步驟把工作流資訊提交到 Lotus Symphony 文件中。
在提交按鈕上新增函式
找到 createPartControl 中的 commitBtn,按照以下程式碼進行修改。當選擇部件時,呼叫 commitWorkflowInfo 方法。
commitBtn.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent arg0) { // TODO Autogenerated method stub } public void widgetSelected(SelectionEvent arg0) { commitWorkflowInfo(); } }); |
commitWorkflowInfo 方法
這個方法從 Document Workflow 應用程式中讀取內容,並呼叫函式把資料寫入當前文件。把以下程式碼複製並貼上到 ShelfView.java 中。
private void commitWorkflowInfo( ) { String wner = ownerTxt.getText(); String reviewer = statusTxt.getText(); writeWorkflowInfo( owner, reviewer ); } |
writeWorkflowInfo
這個方法把工作流資料提交到當前文件中。把以下程式碼複製並貼上到 ShelfView.java 中。
private void writeWorkflowInfo(String owner, String reviewer) { Object model = selectedView.getUNOModel(); XTextTablesSupplier tableSupplier = ( XTextTablesSupplier ) UnoRuntime.queryInterface( XTextTablesSupplier.class, model ); XNameAccess nameAccess = tableSupplier.getTextTables(); try { XTextTable table = ( XTextTable )UnoRuntime.queryInterface ( XTextTable.class,nameAccess.getByName("Workflow")); XCell cell = table.getCellByName( "B2" ); XText text = ( XText ) UnoRuntime.queryInterface(XText.class, cell); text.setString(owner); cell = table.getCellByName("B3"); text = ( XText ) UnoRuntime.queryInterface(XText.class, cell); text.setString(reviewer); } catch (NoSuchElementException e) { // TODO Autogenerated catch block e.printStackTrace(); } catch (WrappedTargetException e) { // TODO Autogenerated catch block e.printStackTrace(); } } |
- 確認以上操作是正確的,單擊 File > Save All。
- 單擊工具欄中的 Run 按鈕。
結果:應用程式啟動;單擊 File > New> Document,螢幕應該與下圖相似。
- 雙擊 Document Library 中的每個文件。
結果:文件會在新的附籤視窗中自動開啟。
- 在“Document 1”、“Document 2”和“Document 3”之間切換。
結果:Workflow 組中的所有者和狀態會自動更新。
- 修改所有者和狀態,單擊 Commit 按鈕。
結果:修改的內容在 Lotus Symphony 文件中自動更新。
本教程帶領您建立了 Lotus Symphony 邊架擴充套件。學習瞭如何建立外掛和外掛擴充套件,以及如何使用 Lotus Symphony 支援的 Java API 讀取和更新 Lotus Symphony 文件的內容。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14751907/viewspace-406613/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IBM Lotus Symphony 七種兵器之 WidgetsIBM
- developerWorks 中國 > Lotus > IBM Lotus Symphony 七種兵器之 Mail MergesDeveloperIBMAI
- Android Studio Plugin 外掛開發教程(一) —— 開發你的第一個外掛AndroidPlugin
- IBM Lotus Symphony 七種兵器之 Mail MergesIBMAI
- 15個對開發人員最佳的Chrome擴充套件外掛Chrome套件
- wordpress外掛開發03-簡單的all in one seo 外掛開發
- 重構:從 0.1 構建一個 Vue 表單驗證外掛Vue
- chrome外掛開發文件Chrome
- 編寫一個簡單的babel外掛Babel
- Web前端開發人員應有的20個Firefox 4外掛Web前端Firefox
- 成為Web開發人員的7個簡單步驟Web
- 老闆要我開發一個簡單的工作流引擎
- 和開發人員討論一個業務需求和簡單實現
- 利用 Docker 構建一個簡單的 java 開發編譯環境DockerJava編譯
- 快速開始構建一個簡單專案
- jQuery外掛開發流程簡單介紹jQuery
- Maven外掛開發教程Maven
- Chrome外掛開發教程Chrome
- Stylus外掛開發教程
- 使用 vite 構建一個表情選擇外掛Vite
- 如何開發一個 PyCharm 外掛PyCharm
- apisix閘道器-構建docker映象構建及外掛化開發APIDocker
- chrome外掛開發簡介(一)——開發入門Chrome
- 開發了一個 JATO for JBuilder 的外掛UI
- IE8開發人員工具教程(一)
- 寫了一個簡單好用的彈出層外掛
- eslint外掛開發教程EsLint
- Plugins:開發人員必備的Firefox外掛(個人在用)PluginFirefox
- 一個簡單的構建React元件動畫方案React元件動畫
- [轉]:如何快速構建一個簡單的程式
- 從頭開發一個Flutter外掛(一)開發流程Flutter
- 【實踐思考】自己開發一個掘金黑名單功能外掛
- [需求建議]外掛建議:建議出一個時間軸外掛
- WordPress外掛開發例項教程 - 版權外掛
- 簡簡單單的Vue3(外掛開發,路由系統,狀態管理)Vue路由
- 為 Webform Server 開發 IBM Lotus FormsWebORMServerIBM
- 原生 JS實現一個簡單分頁外掛JS
- [需求建議]看到我們們的ot 用到外掛和鉤子 不知官方能否開發一個會員外掛呢