xmind導入導出支持圖片功能源碼改造

xmind導入導出支持圖片功能
在開發用例管理平臺的過程中,需要使用xmind來管理用例。所以也涉及到xmind用例的導入導出功能,
在開始的時候,xmind文件中沒有圖片,所以使用xmind,xmindparser包就可以完成改任務。現在新增需求,
要求支持xmind文件中圖片的導入導出。原有的包,并不支持圖片的操作,所以需要對這兩個包進行一些改造。
1.環境 python3.8
2.xmind版本,xmind8,xmindzen
3.需要的python包 xmind包,xmindparser包

xmindparser包改造
針對xmind8版本,需要改動xreader.py文件的image_of方法
原方法:
def image_of(node):
? ? img = node.find('img')

? ? if img is not None:
? ? ? ? return '[Image]'
因為項目需要圖片的內容信息,還有圖片的大小,所以將圖片的附件、高、寬,拼接一起返回
改造后方法:
def image_of(node):
? ? img = node.find('img')
? ? if img is not None:
? ? ? ? src_attribute = img.get('{http://www.w3.org/1999/xhtml}src')
? ? ? ? height_attribute = img.get('{http://www.w3.org/2000/svg}height')
? ? ? ? width_attribute = img.get('{http://www.w3.org/2000/svg}width')
? ? ? ? return str(src_attribute) + ':' + str(height_attribute) + ':' + str(width_attribute)
? ? return None

針對xmindzen版本,需要改動zenreader.py文件的image_of方法
def image_of(node):
? ? img = node.get('image', None)
? ? if img is not None:
? ? ? ? src_attribute = img.get('src')
? ? ? ? height_attribute = img.get('height')
? ? ? ? width_attribute = img.get('width')
? ? ? ? return str(src_attribute) + ':' + str(height_attribute) + ':' + str(width_attribute)
? ? return None

使用改造后方法,下載xmind的圖片
xmind_file = /data/xmind/test.xmind
xmind_content_dict = xmind_to_dict(xmind_file)
zFile = ZipFile(xmind_file, 'r')
image_data = zFile.read('attachments/xxxxxxxx')# 這就是改造后image_of方法中的src_attribute字段
file_name = '/data/image/image.jpg'
with open(file_name, 'wb') as f:
?? ?f.write(image_data)
即可將文件保存到file_name

xmind庫改造
const.py新增內容如下
# 圖片
IMAGE = 'xhtml:img'
IMAGE_SRC = 'xhtml:src'
IMAGE_HEIGHT = 'svg:height'
IMAGE_WIDTH = 'svg:width'

markerref.py新增內容如下
class ImageElement(WorkbookMixinElement):
? ? TAG_NAME = const.IMAGE

? ? def __init__(self, node=None, ownerWorkbook=None):
? ? ? ? super(ImageElement, self).__init__(node, ownerWorkbook)

? ? def getXhtmlSrc(self):
? ? ? ? '''取消前綴,只留圖片名稱,后續直接在attachments文件夾下找該圖片'''
? ? ? ? return self.getAttribute(const.IMAGE_SRC).replace('xap:attachments/', '')

? ? def getImageHeight(self):
? ? ? ? return self.getAttribute(const.IMAGE_HEIGHT)

? ? def getImageWidth(self):
? ? ? ? return self.getAttribute(const.IMAGE_WIDTH)

? ? def setXhtmlSrc(self, src):
? ? ? ? return self.setAttribute(const.IMAGE_SRC, f"xap:attachments/{src}")

? ? def setImageHeight(self, height):
? ? ? ? return self.setAttribute(const.IMAGE_HEIGHT, height)

? ? def setImageWidth(self, width):
? ? ? ? return self.setAttribute(const.IMAGE_WIDTH, width)

topic.py文件新增如下內容
TopicElement類下的
getData函數的data字段新增'image': self.getImage()
TopicElement類下新增三個函數
def getImage(self):
?? ?image = self._get_image()
?? ?if image:
?? ??? ?image = ImageElement(image, self.getOwnerWorkbook())
?? ??? ?return {
?? ??? ??? ?'src': image.getXhtmlSrc(),
?? ??? ??? ?'height': image.getImageHeight(),
?? ??? ??? ?'width': image.getImageWidth()
?? ??? ?}

def setImage(self, src, height, width):
?? ?image = self._get_image()
?? ?if not image:
?? ??? ?image = ImageElement(None, self.getOwnerWorkbook())
?? ??? ?self.appendChild(image)
?? ?else:
?? ??? ?image = ImageElement(image, self.getOwnerWorkbook())
?? ?image.setXhtmlSrc(src)
?? ?image.setImageHeight(height)
?? ?image.setImageWidth(width)
def _get_image(self):
?? ?return self.getFirstChildNodeByTagName(const.IMAGE)

改造后xmind增加圖片附件的流程

MANIFEST_TEMPLATE = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<manifest xmlns="urn:xmind:xmap:xmlns:manifest:1.0" password-hint="">
<file-entry full-path="attachments/" media-type=""/>
{}
<file-entry full-path="content.xml" media-type="text/xml"/>
<file-entry full-path="META-INF/" media-type=""/>
<file-entry full-path="META-INF/manifest.xml" media-type="text/xml"/>
<file-entry full-path="comments.xml" media-type="text/xml"/>
<file-entry full-path="styles.xml" media-type="text/xml"/>
</manifest>
"""
image_name = '圖片名稱.png'
image_data = b'文件byte數據'
height = 300
width = 300

xmind_file_path = f"{str(uuid.uuid4())}.xmind"
workbook = xmind.load(path)
# get the first sheet(a new workbook has a blank sheet by default)
sheet = workbook.getPrimarySheet()
sheet.setTitle(tree['data']['text']) ?# 設置畫布名稱
root_topic = sheet.getRootTopic()
root_topic.setTitle(tree['data']['text']) ?# 設置主題名稱
sub_topic = root_topic.addSubTopic() # 新增child主題
sub_topic.setImage(img_name, height, width) # 設置圖片
xmind.save(workbook, path=xmind_file_path) # 先保存

for img_name, img_data in image_dict.items():
?? ?azip.writestr(f'attachments/{img_name}', data=img_data) ?# 將圖片寫入attachments中
?? ?manifest_img += f'<file-entry full-path="attachments/{img_name}" media-type="image/{img_name.split(".")[-1]}"/>'
azip.writestr(f'META-INF/manifest.xml', data=MANIFEST_TEMPLATE.format(manifest_img)) ?# 寫入META-INF/manifest.xml文件
azip.close()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/39209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39209.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# 編程中互斥鎖的使用

C# 中的互斥鎖 互斥鎖是 C# 中使用的同步原語&#xff0c;用于控制多個線程或進程對共享資源的訪問。其目的是確保在任何給定時間只有一個線程或進程可以獲取互斥鎖&#xff0c;從而提供互斥。 C# 中互斥鎖的優點 可以使用互斥鎖 (Mutex) 并享受其帶來的好處。 1. 共享資源…

德國威步的技術演進之路(下):從云端許可管理到硬件加密狗的創新

從單機用戶許可證到WkNET網絡浮點授權的推出&#xff0c;再到引入使用次數和豐富的時間許可證管理&#xff0c;德國威步產品不斷滿足市場對靈活性和可擴展性的需求。TCP/IP浮動網絡許可證進一步展示了威步技術在網絡時代的創新應用。借助于2009年推出的借用許可證以及2015年推出…

mac磁盤工具如何合并分區 macos 磁盤工具 無法抹除 磁盤管理軟件哪個使用率最高

一、什么是NTFS格式分區 NTFS格式分區是微軟公司開發的諸多文件系統中的一種。NTFS格式分區是一種文件系統&#xff0c;磁盤只有在安裝了文件系統后才能被正常使用&#xff0c;文件系統的格式有非常多&#xff0c;常見的有FAT 32和NTFS。 作為常見文件系統&#xff0c;NTFS格式…

無人機集群協同搜索研究綜述

源自&#xff1a;指揮控制與仿真 作者&#xff1a;劉圣洋, 宋婷, 馮浩龍, 孫玥, 韓飛 注&#xff1a;若出現無法顯示完全的情況&#xff0c;可 V 搜索“人工智能技術與咨詢”查看完整文章 摘要 無人機集群協同區域搜索能夠有效地獲取任務區域地面信息,降低環境不確定度。基…

買賣股票的最佳時期含冷凍期(leetcode)

個人主頁&#xff1a;Lei寶啊 愿所有美好如期而遇 也就有這樣的狀態轉移方程&#xff1a; 買入&#xff1a;dp[i][0] max(dp[i-1][1] - prices[i], dp[i-1][0]); 可買入&#xff1a;dp[i][1] max(dp[i-1][1], dp[i-1][2]); 冷凍期&#xff1a;dp[i][2] dp[i-1][0] prices…

使用ChatGPT自動生成測試用例思維導圖

使用ChatGPT自動生成測試用例思維導圖 引言ChatGPT在測試用例編寫中的應用全面覆蓋測試場景邊界測試避免測試用例重復 借助ChatGPT生成測試用例思維導圖準備工作步驟一&#xff1a;與ChatGPT對話步驟二&#xff1a;生成思維導圖代碼 結語 引言 在編寫測試用例時&#xff0c;測…

基于Python Django的房價數據分析平臺,包括大屏和后臺數據管理,有線性、向量機、梯度提升樹、bp神經網絡等模型

背景 隨著城市化進程的加速和房地產市場的快速發展&#xff0c;房價已成為經濟學、社會學等多學科交叉研究的熱點問題。為了更精確地分析和預測房價&#xff0c;數據分析和機器學習技術被廣泛應用。在此背景下&#xff0c;開發一個基于Python Django的房價數據分析平臺具有重要…

職業技能大賽引領下物聯網專業實訓教學的改革研究

隨著物聯網技術的迅猛發展&#xff0c;作為培養高技能應用型人才的高職院校&#xff0c;面臨著將理論與實踐深度結合&#xff0c;以滿足行業對物聯網專業人才新要求的挑戰。職業技能大賽作為一種重要的教育評價與促進機制&#xff0c;為物聯網專業實訓教學的改革提供了新的視角…

面試題004-Java-Java多線程(下)

面試題004-Java-Java多線程(下) 這里寫目錄標題 面試題004-Java-Java多線程(下)題目自測題目答案1. synchronized 關鍵字的作用&#xff1f;2. volatile 關鍵字的作用&#xff1f;3. synchronized 和 volatile 的區別&#xff1f;4. synchronized 和 ReentrantLock 的區別&…

成人高考本科何時報名-深職訓學校幫您規劃學習之路

你有想過繼續深造自己的學歷嗎&#xff1f;也許你已經工作多年&#xff0c;但總覺得學歷是一塊心病&#xff0c;想要通過成人高考本科來提升自己。不用著急&#xff0c;今天我們來聊一聊成人高考本科的報名時間&#xff0c;以及深職訓學校如何幫助你順利完成報名。 深圳成人高…

LeetCode-刷題記錄-滑動窗口合集(本篇blog會持續更新哦~)

一、滑動窗口概述 滑動窗口&#xff08;Sliding Window&#xff09;是一種用于解決數組&#xff08;或字符串&#xff09;中子數組&#xff08;或子串&#xff09;問題的有效算法。 Sliding Window核心思想&#xff1a; 滑動窗口技術的基本思想是維護一個窗口&#xff08;一般…

怎樣在Python中使用oobabooga的API密鑰,通過端口5000獲取模型列表的授權

題意&#xff1a; oobabooga-textgen-web-ui how to get authorization to view model list from port 5000 via the oobas api-key in python 怎樣在Python中使用oobabooga的API密鑰&#xff0c;通過端口5000獲取模型列表的授權 問題背景&#xff1a; I wish to extract an…

fastapi+vue3前后端分離開發第一個案例整理

開發思路 1、使用fastapi開發第一個后端接口 2、使用fastapi解決cors跨域的問題。cors跨域是瀏覽器的問題&#xff0c;只要使用瀏覽器&#xff0c;不同IP或者不同端口之間通信&#xff0c;就會存在這個問題。前后端分離是兩個服務&#xff0c;端口不一樣&#xff0c;所以必須要…

PCA和PCoA分析的python代碼

主成分分析(PCA)和主坐標分析(PCoA)都是數據降維和可視化的常用方法,但它們在適用場景和計算方法上有一些重要區別。 主成分分析(PCA) 定義: PCA是一種線性降維方法,通過正交變換將原始數據轉化為一組線性不相關的變量(主成分)。這些主成分是數據中方差最大的方向。…

XLSX + LuckySheet + LuckyExcel實現前端的excel預覽

文章目錄 功能簡介簡單代碼實現效果參考 功能簡介 通過LuckyExcel的transformExcelToLucky方法&#xff0c; 我們可以把一個文件直接轉成LuckySheet需要的json字符串&#xff0c; 之后我們就可以用LuckySheet預覽excelLuckyExcel只能解析xlsx格式的excel文件&#xff0c;因此對…

.NET 漏洞分析 | 某ERP系統存在SQL注入

01閱讀須知 此文所提供的信息只為網絡安全人員對自己所負責的網站、服務器等&#xff08;包括但不限于&#xff09;進行檢測或維護參考&#xff0c;未經授權請勿利用文章中的技術資料對任何計算機系統進行入侵操作。利用此文所提供的信息而造成的直接或間接后果和損失&#xf…

Java中s-EJB 與 e-EJB的區別

在Java中&#xff0c;關于“s-EJB”與“e-EJB”的區分&#xff0c;實際上可能存在一定的誤解或混淆&#xff0c;因為在標準的EJB&#xff08;Enterprise JavaBeans&#xff09;術語中&#xff0c;并沒有直接稱為“s-EJB”和“e-EJB”的明確分類。然而&#xff0c;為了嘗試解答這…

【Postman gRPC測試全攻略】探索微服務通信的新紀元

標題&#xff1a;【Postman gRPC測試全攻略】探索微服務通信的新紀元 gRPC是一種高性能、開源和通用的RPC框架&#xff0c;由Google主導開發&#xff0c;它使用Protocol Buffers作為接口描述語言和消息交換格式。Postman作為API開發的利器&#xff0c;也提供了對gRPC服務的測試…

封裝2個函數

1 #include "key1.h"2 //封裝EXTI章節函數3 void hal_exti_init(int exti,unsigned int i)4 {5 switch(exti)6 {7 case 9:8 //使能GPIOF外設時鐘9 RCC->MP_AHB4ENSETR | (0x1<<5);10 //將PF9設置為輸出模式11 …

MyBatis(22)如何在 MyBatis 中使用注解而不是 XML 映射文件

在 MyBatis 中&#xff0c;使用注解而不是 XML 映射文件來進行 SQL 映射是一種更為簡潔直觀的方式&#xff0c;尤其適用于 SQL 語句較少的場景。通過注解&#xff0c;開發者可以直接在接口方法上聲明 SQL 語句&#xff0c;這樣可以減少項目中的配置文件數量&#xff0c;使得項目…