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()