ONLYOFFICE是一項功能強大的開源文檔編輯器,可以將文本文檔、電子表格和演示文稿、電子表單編輯功能集成至任何編程語言編寫的 Web 應用程序中。最新的7.5版本編輯器可以支持編輯PDF文件(批注、繪圖等)。在本文中,我們會帶你了解如何將ONLYOFFICE集成到你的Python應用程序中。
為此,我們將在 Python 上創建一個簡單的文檔管理系統,并將 ONLYOFFICE 文檔編輯器進行集成,其實它比你想象的更簡單。
Python 中的 DMS
在這一part中,我們先編寫一個 Python 應用程序,然后在示例中展示與 ONLYOFFICE 的集成。你計劃集成編輯器的應用程序很可能具有需要打開以進行查看/編輯的文件列表。因此,讓我們創建一個具有此功能的應用程序,并且還應該支持下載文件。
我們使用 Bottle 框架。你可以用 pip install Bottle 命令將其安裝在工作目錄中。現在我們需要創建文件main.py(應用程序的代碼)和index.tpl(模板),然后將以下代碼添加到main.py文件中:
from bottle import route, run, template, get, static_file # connecting the framework and the necessary components
@route('/') # setting up routing for requests for /
def index():return template('index.tpl') # showing template in response to requestrun(host="localhost", port=8080) # running the application on port 8080
當我們啟動應用程序時,會在 http://localhost:8080 上看到一個空白頁面。由于文檔服務器無法從頭開始創建新文檔,因此我們必須添加默認文件并在模板中形成其名稱列表。因此,我們創建一個文件夾 files ,并在其中放入 3 個文件(docx、xlsx 和 pptx)。
我們將使用 listdir 組件來讀取它們的名稱。
from os import listdir
現在讓我們為 files 文件夾中的所有文件名創建一個變量:
sample_files = [f for f in listdir('files')]
要在模板中使用此變量,我們需要通過template方法傳遞它:
def index():return template('index.tpl', sample_files=sample_files)
讓我們在模板中顯示這個變量:
%for file in sample_files:<div><span>{{file}}</span></div>
% end
重新啟動應用程序后,我們可以在頁面上看到文件名列表。現在我們必須使所有應用程序用戶都可以使用這些文件。
這是一種新方法:
@get("/files/<filepath:re:.*\.*>")
def show_sample_files(filepath):return static_file(filepath, root="files")
在 Python 應用程序中查看文檔
使用 ONLYOFFICE 編輯器安裝文檔服務器。有很多安裝選項,但我們建議使用 Docker:
docker run -itd -p 80:80 onlyoffice/documentserver-de
連接模板中的文檔編輯器 API:
<script type="text/javascript" src="editor_url/web-apps/apps/api/documents/api.js"></script>
editor_url 是文檔編輯器的鏈接。
是一個按鈕,用于打開每個文件進行查看:
<button onclick="view('files/{{file}}')">view</button>
現在我們需要添加一個帶有 id 的 div:
<div id="editor"></div>
文檔編輯器將在此 div 中打開。但只有在我們調用將打開編輯器的函數之后才行。
<script>
function view(filename) {if (/docx$/.exec(filename)) {filetype = "text"}if (/xlsx$/.exec(filename)) {filetype = "spreadsheet"}if (/pptx$/.exec(filename)) {filetype = "presentation",title: filename}new DocsAPI.DocEditor("editor",{documentType: filetype,document: {url: "host_url" + '/' + filename,title: filename},editorConfig: {mode: 'view'}});}
</script>
DocEditor 函數有兩個參數:將打開編輯器的元素的 id 和包含編輯器設置的 JSON。
所有參數都可以在官方API文檔中找到。在此示例中,我們使用強制參數 documentType 、 document.url 和 editorConfig.mode 。我們還添加標題 - 這是將在編輯器中顯示的文件名。
文檔類型 (documentType) 將通過其格式進行標識(docx 表示文本,xlsx 表示電子表格,pptx 表示演示文稿)。
注意 document.url。這是我們要打開的文件的鏈接。
現在,我們已經做好了在 Python 應用程序中查看文檔的準備。
編輯文件
讓我們添加“編輯”按鈕:
<button onclick="edit('files/{{file}}')">edit</button>
現在我們需要創建一個新函數來打開文件進行編輯。它類似于 View 函數,所以讓我們將普通的部分作為一個單獨的函數。
現在我們有3個函數:
<script>var editor;function view(filename) {if (editor) {editor.destroyEditor()}editor = new DocsAPI.DocEditor("editor",{documentType: get_file_type(filename),document: {url: "host_url" + '/' + filename,title: filename},editorConfig: {mode: 'view'}});}function edit(filename) {if (editor) {editor.destroyEditor()}editor = new DocsAPI.DocEditor("editor",{documentType: get_file_type(filename),document: {url: "host_url" + '/' + filename,title: filename}});}function get_file_type(filename) {if (/docx$/.exec(filename)) {return "text"}if (/xlsx$/.exec(filename)) {return "spreadsheet"}if (/pptx$/.exec(filename)) {return "presentation"}}
</script>
destroyEditor 將關閉已打開的編輯器。
默認情況下, editorConfig 參數的值為 {"mode": "edit"} ,這就是 edit() 函數中缺少它的原因。
現在將打開文件進行編輯。
協同編輯文檔
協同編輯是通過在編輯器設置中對同一文檔使用相同的 document.key 來實現的。如果沒有此密鑰,編輯器將在您每次打開文件時創建編輯會話。
為了使用戶連接到同一編輯會話進行共同編輯,我們需要為每個文檔設置唯一的密鑰。讓我們使用文件名+“_key”格式的密鑰。我們需要將其添加到存在document的所有配置中。
document: {url: "host_url" + '/' + filepath,title: filename,key: filename + '_key'},
保存文件
ONLYOFFICE 通常會存儲您在其中工作時對文檔所做的所有更改。關閉編輯器后,Document Server 構建要保存的文件版本并將請求發送到callbackUrl 地址。該請求包含 document.key 和剛剛構建的文件的鏈接。
在生成中,您將使用 document.key 查找文件的舊版本并將其替換為新版本。在我們的例子中,我們沒有任何數據庫,所以我們只是使用callbackUrl 發送文件名。
在editorConfig.callbackUrl的設置中指定callbackUrl。添加此參數后,edit()方法將如下所示:
function edit(filename) {const filepath = 'files/' + filename;if (editor) {editor.destroyEditor()}editor = new DocsAPI.DocEditor("editor",{documentType: get_file_type(filepath),document: {url: "host_url" + '/' + filepath,title: filename, key: filename + '_key'},editorConfig: {mode: 'edit',callbackUrl: "host_url" + '/callback' + '&filename=' + filename // add file name as a request parameter}});}
現在我們需要編寫一個方法,在將 post 請求發送到 /callback 地址后保存文件:
@post("/callback") # processing post requests for /callback
def callback():if request.json['status'] == 2:file = requests.get(request.json['url']).contentwith open('files/' + request.query['filename'], 'wb') as f:f.write(file)return "{\"error\":0}"
# status 2 是構建的文件。有關所有狀態的更多信息可以在 API 文檔中找到。
現在,關閉編輯器后,文件的新版本將保存到存儲中。
管理用戶
如果您的應用程序中有用戶,請將他們的標識符(id 和名稱)寫入編輯器的配置中。這樣您就可以看到到底是誰在編輯文檔。
作為示例,讓我們添加在界面中選擇用戶的功能:
<select id="user_selector" onchange="pick_user()"><option value="1" selected="selected">JD</option><option value="2">Turk</option><option value="3">Elliot</option><option value="4">Carla</option>
</select>
讓我們在標簽 <script> 的開頭添加函數 pick_user() 的調用。在函數本身中,我們將初始化負責 id 和用戶名的變量。
function pick_user() {const user_selector = document.getElementById("user_selector");this.current_user_name = user_selector.options[user_selector.selectedIndex].text;this.current_user_id = user_selector.options[user_selector.selectedIndex].value;}
現在我們需要使用 editorConfig.user.id 和 editorConfig.user.name 在編輯器配置中添加用戶設置。讓我們將這些參數添加到文件編輯功能中的編輯器配置中。
function edit(filename) {const filepath = 'files/' + filename;if (editor) {editor.destroyEditor()}editor = new DocsAPI.DocEditor("editor",{documentType: get_file_type(filepath),document: {url: "host_url" + '/' + filepath,title: filename},editorConfig: {mode: 'edit',callbackUrl: "host_url" + '/callback' + '?filename=' + filename,user: {id: this.current_user_id,name: this.current_user_name}}});}
我們希望這個簡單的示例能夠幫助您將 ONLYOFFICE 與 Python 應用程序集成。更多集成示例可以在 GitHub上找到。