亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Office調研——獲取Office增量的三種方法的可行性

2023-12-07 02:58:44
23
0

問題提出原因、背景

在(zai)(zai)(zai)高可用云(yun)電(dian)腦的項目中(zhong),需(xu)要(yao)將云(yun)電(dian)腦中(zhong)的所有文(wen)件(jian)(jian)(jian)同(tong)(tong)步到另一臺云(yun)電(dian)腦中(zhong),這些文(wen)件(jian)(jian)(jian)中(zhong)就有許(xu)多是(shi)Office文(wen)件(jian)(jian)(jian)。而在(zai)(zai)(zai)實際(ji)運(yun)行(xing)中(zhong)發(fa)現,Office源文(wen)件(jian)(jian)(jian)的微小改(gai)動,都(dou)會使得整個Office文(wen)件(jian)(jian)(jian)都(dou)需(xu)要(yao)重(zhong)新同(tong)(tong)步,例如,在(zai)(zai)(zai)Word文(wen)件(jian)(jian)(jian)的末尾中(zhong),添加一個逗(dou)號,整個Word文(wen)件(jian)(jian)(jian)都(dou)發(fa)生了(le)變化(在(zai)(zai)(zai)磁(ci)盤層面觀(guan)察(cha))。這樣同(tong)(tong)步傳(chuan)輸(shu)時(shi)耗費的時(shi)間(jian)和網絡資源都(dou)很(hen)大。

因此,需要(yao)調研Office的緩存機制,了解為何Office的微小改(gai)動會(hui)導致整個文件(jian)都(dou)發生變化,繼(ji)而得出該(gai)問(wen)題的解決辦(ban)法。

由上一(yi)篇“Office調研——Office的緩存機制”的文(wen)章中通過調研得出了(le)Office的緩存、落盤機制,并且(qie)證明了(le)是“由于Office軟件在每次保存中,都將全量(liang)數據(包括(kuo)增(zeng)量(liang))寫入到新的文(wen)件中,所(suo)以從磁(ci)盤層面觀察(cha),無(wu)論是多微(wei)小(xiao)(xiao)的改動,都是產生了(le)一(yi)個新文(wen)件”,導致(zhi)Office的微(wei)小(xiao)(xiao)改動會導致(zhi)整個文(wen)件都發(fa)生變化。

本篇繼(ji)續調研上一篇“Office調研——Office的(de)緩(huan)存機(ji)制”的(de)文章(zhang)中提(ti)出的(de)獲(huo)取Office增量的(de)三(san)種方法是否可行。

1.問題描述

  1. 方法1:將ppt解壓,變成分散的文件,對比各個文件的差異,按照文件的方式去獲取增量內容。是否可行?
  2. 方法2:利用python,讀取ppt,在python內比較兩個ppt之間的差異,將差異部分以某種文件的形式保存下來,得到保存增量數據的文件。是否可行?
  3. 方法3:利用VBA編程,將代碼直接插入到Office里面,獲取Office的增量數據。是否可行?

2.方法1:將ppt解壓,變成分散的文件,對比各個文件的差異

2.1.對 word、excel、ppt解壓后(zip 解壓)的文件結構,如下:

Word excel ppt

2.2.修改word內容,記錄word解壓后的文件的改變情況

修改前文件大小 修改后文件大小
text001.docx :570KB
解壓后:604KB
圖片:557KB
其他:43.9KB
text001.docx :1.095MB
解壓后:1.10MB
圖片:1050KB
其他:45.7KB
其中新增圖片:525KB

若按(an)照docx文件傳輸,則需要傳輸 1.095 MB

若按照解(jie)壓(ya)后(hou)的(de)文件傳輸(shu),則至(zhi)少需要傳輸(shu) 526.317KB ,最(zui)多需要傳輸(shu) 1.10MB

2.3.修改excel內容,記錄excel解壓后的文件的改變情況

修改前文件大小 修改后文件大小
   

若按照excel文件傳輸,則需(xu)要(yao)傳輸 9KB

若按(an)照解壓后的文(wen)件傳輸,則(ze)至少需要傳輸 0.2KB ,最多需要傳輸 28KB

2.4.修改ppt內容,記錄ppt解壓后的文件改變情況

修改前文件大小 修改后文件大小

若(ruo)按(an)照excel文件傳輸,則(ze)需(xu)要傳輸 346KB

若按照解壓后的文(wen)件(jian)傳(chuan)輸,則至少需要傳(chuan)輸 11KB ,最多需要傳(chuan)輸 407KB

2.5.使用 beyond compare 工具對比文件前后改變情況

Word:增加了兩行文字,增加了一(yi)張圖片(pian)

Excel:增加了兩個(ge)單元(yuan)格內容。

ppt:第一張(zhang)幻燈片(pian)調整了文字框,沒有增(zeng)加文字。

新增了(le)2,3,4,5,6幻(huan)燈(deng)片,幻(huan)燈(deng)片內容都為文(wen)字

解壓后傳輸(shu) 26185 字節,約 25.57KB

pptx傳輸 353780 字(zi)節(jie),約 345.49KB

傳(chuan)輸量約為原本的 7.4 01%

2.6.結論

方法1可(ke)(ke)行(xing)。將ppt,word,excel文件解(jie)壓,變成(cheng)分散的文件,對比各個(ge)文件的差異(yi),然后傳輸這些差異(yi)文件,為一個(ge)可(ke)(ke)行(xing),且過程不太復雜的方法。

3.方法2:利用python,讀取ppt,在python內比較兩個ppt之間的差異,將差異部分以某種文件的形式保存下來,得到保存增量數據的文件

3.1.以ppt文件為例,利用python-pptx庫實現獲取ppt的增量數據,編寫demo代碼

demo代碼:

import pathlib
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.shapes import MSO_SHAPE_TYPE
# 借用openpyxl的單位轉換
from openpyxl.utils.units import EMU_to_pixels as e2p

def output_diff_dict(diff_dict):
	print(f'========== print diff dict ==========')
	for key, value in diff_dict.items():
		print(f'key = {key} | value = {value} | type = {type(value)}')

path = list(pathlib.Path.cwd().parents)[1].joinpath('D:\\xxxxx')
img_out_path = path.joinpath('ppt_out_images')
txt_out_path = path.joinpath('ppt_notes.txt')

def create_new_ppt(origin_ppt, diff_dict):
	for key,value in diff_dict.items():
		key_temp = key.split(",")
		key_len = len(key_temp)
		
		# 添加頁
		# todo
		if key_len == 1:
			if value == 'NULL':
				origin_ppt.slides._sldIdLst.remove[int(key_temp[0])] 
			else:
				# todo
				print('need add slides')
		
		# 添加 shape
		# todo
		if key_len == 2:
			shapes_temp = origin_ppt.slides[int(key_temp[0])].shapes
			if value == 'NULL':
				# todo
				print('need delete shape')
			else:
				if (value.shape_type == MSO_SHAPE_TYPE.PICTURE):
					#shapes_temp.add_picture(value, left = value.left, top = value.top)
					
					# 獲取二進制字符流
					imdata = value.image.blob
					# 判斷文件后綴類型
					imagetype = value.image.content_type
					typekey = imagetype.find('/') + 1
					imtype = imagetype[typekey:]
					
					# 圖片生成
					image_file = ".\\pic001" + "." + imtype

					file_str=open(image_file,'wb')
					file_str.write(imdata)
					file_str.close()
					
					shapes_temp.add_picture(image_file, left = value.left, top = value.top, width=value.width, height=value.height)
				elif (value.has_text_frame):
					new_text = shapes_temp.add_textbox(left=value.left, top=value.top, width=value.width, height=value.height).text_frame
					new_text.paragraphs[0].text = value.text_frame.text
					
				else:
					print('need add shape')
		
		# 修改 shape
		# todo
		
		if key_len == 3:
			slide_layouts_temp = origin_ppt.slide_master.slide_layouts
			shape_temp = origin_ppt.slides[int(key_temp[0])].shapes[int(key_temp[1])]
			# text 類型
			if key_temp[2] == 'text':
				if value == 'NULL':
					#todo
					print('need delete text')
				else:
					shape_temp.text_frame.text = value
			# image 類型
			if key_temp[2] == 'image':
				if value == 'NULL':
					print('need delete image')
				else:
					shape_temp.image = value
				
	print('save ppt.')
	origin_ppt.save("text003.pptx")

# 獲取到對象
in_path1 = path.joinpath('test001.pptx')
prs1 = Presentation(in_path1)
in_path2 = path.joinpath('test002.pptx')
prs2 = Presentation(in_path2)

# 存儲位置 + 內容
diff_dict = {}

# 比較頁數,存儲不同的整頁
print(f'========== compare slide len ==========')
slide1_len = len(prs1.slides)
slide2_len = len(prs2.slides)
# EMU單位,1 Pixel = 9525 EMU
w, h = prs1.slide_width, prs1.slide_height
print(f'ppt1 總共 {slide1_len} 頁,頁寬 {e2p(w)} px,頁高 {e2p(h)} px')
w, h = prs2.slide_width, prs2.slide_height
print(f'ppt2 總共 {slide2_len} 頁,頁寬 {e2p(w)} px,頁高 {e2p(h)} px')

less_slide_len = slide1_len
if(slide1_len != slide2_len):
	if(slide1_len < slide2_len):
		for i in range(slide1_len, slide2_len):
			diff_dict[f"{i}"] = prs2.slides[i]
	else:
		less_slide_len = slide2_len
		for i in range(slide2_len, slide1_len):
			diff_dict[f"{i}"] = 'NULL'

# 比較每頁,存儲每頁不同
for i in range(less_slide_len):
	print(f'========== compare slide[{i}] ==========')
	slide1 = prs1.slides[i]
	slide2 = prs2.slides[i]
	slide_key = f"{i}"
	
	# 比較每頁里面的形狀shape,shape包含ppt里面一切可視元素
	shape1_len = len(slide1.shapes)
	shape2_len = len(slide2.shapes)
	less_shape_len = shape1_len
	
	if(shape1_len != shape2_len):
		if(shape1_len < shape2_len):
			for j in range(shape1_len, shape2_len):
				shape_key = slide_key + f",{j}"
				diff_dict[shape_key] = slide2.shapes[j]
		else:
			less_shape_len = shape2_len
			for j in range(shape2_len, shape1_len):
				shape_key = slide_key + f",{j}"
				diff_dict[shape_key] = 'NULL'

	print(f'ppt1 總共 {shape1_len} 個shape')
	print(f'ppt2 總共 {shape2_len} 個shape')
	
	# 比較每個形狀
	for j in range(less_shape_len):
		print(f'========== compare shape[{j}] ==========')
		shape1 = slide1.shapes[j]
		shape2 = slide2.shapes[j]
		shape_key = slide_key + f",{j}"
		
		# 比較shape里的文本
		if (shape1.has_text_frame) :
			text_key = shape_key + ",text"
			
			if (shape2.has_text_frame):
				text1 = shape1.text_frame.text
				text2 = shape2.text_frame.text
				print(f'ppt1 = {text1}')
				print(f'ppt2 = {text2}')
				if( text1 != text2):
					print(f'text different.')
					diff_dict[text_key] = text2
			else:
				print(f'ppt2 has not text.')
				diff_dict[text_key] = 'NULL'
		
		# 比較shape里的圖片
		if (shape1.shape_type == MSO_SHAPE_TYPE.PICTURE):
			image_key = shape_key + ",image"
			
			if (shape2.shape_type == MSO_SHAPE_TYPE.PICTURE):
				img1 = shape1.image
				img2 = shape2.image
				if( img1 != img2):
					print(f'image different.')
					diff_dict[image_key] = img2
			else:
				print(f'ppt2 has not image.')
				diff_dict[image_key] = 'NULL'
		
output_diff_dict(diff_dict)

create_new_ppt(prs1, diff_dict)

3.2.結論

方法2可行。但提(ti)取(qu)出增量(liang)數據需要原文(wen)件(jian)和新文(wen)件(jian),將兩個文(wen)件(jian)讀取(qu)到python內存中比較,代碼需要循環比較,過程(cheng)復雜(za)。

4.方法3:利用VBA編程,將代碼直接插入到Office里面,獲取Office的增量數據

4.1.以ppt文件為例,調研VBA編程可以獲取到ppt對象模型中的全量數據,還是增量數據。

經過調研、代碼實踐可知,VBA 編(bian)程(cheng)中獲取的 ppt 對象數(shu)據為全量數(shu)據,證明如下:

1. 利用VBA代碼訪問(wen)打開的 ppt 中(zhong)的對象(xiang),檢查其提取該對象(xiang)的文本內容。

在未保存時,提取的結果為該對象的所(suo)有(you)文(wen)本(不區(qu)分原有(you)和新(xin)增)

在按下(xia) “CTRL+S” 保存時,提取的結果依然為該對象的所有(you)文本(不區(qu)分原有(you)和新(xin)增)

2. 對官(guan)方(fang)網站提供的(de)(de)API接口進(jin)(jin)行(xing)查詢,未發現專(zhuan)門存(cun)儲(chu)增(zeng)量數據的(de)(de)對象(xiang)。從API文(wen)檔中(zhong)(zhong)可以(yi)看出,ppt在(zai)(zai)內存(cun)中(zhong)(zhong)是以(yi)一個個對象(xiang)進(jin)(jin)行(xing)存(cun)儲(chu)的(de)(de),該(gai)對象(xiang)包含(han)了ppt的(de)(de)所有(you)信息,用戶在(zai)(zai)編輯ppt時,實際上就在(zai)(zai)動態(tai)地修改內存(cun)中(zhong)(zhong)的(de)(de)對象(xiang)(對象(xiang)中(zhong)(zhong)存(cun)儲(chu)的(de)(de)數據總是原有(you)+增(zeng)量,即最(zui)新(xin)的(de)(de)全量數據),用戶敲(qiao)下CTRL+S時,系統對內存(cun)中(zhong)(zhong)的(de)(de)所有(you)ppt對象(xiang)進(jin)(jin)行(xing)落盤存(cun)儲(chu),并覆蓋原來(lai)的(de)(de)ppt文(wen)件(jian),形成新(xin)的(de)(de)ppt文(wen)件(jian)。

3. 即使ppt在緩存中把原有的數(shu)據(ju)和(he)增量的數(shu)據(ju)分開(kai)存儲(chu)了,在VBA層面(mian)也是不可(ke)知的,因(yin)為VBA是調(diao)用ppt的API進(jin)行(xing)訪問(wen),API中沒有對增量數(shu)據(ju)的訪問(wen),則(ze)VBA無法(fa)獲(huo)取增量數(shu)據(ju)。

4.1.1.結論

由以上3點可以推斷,利用VBA工(gong)具也只能先提取(qu)出(chu)ppt的全量(liang)數(shu)(shu)據(ju),再與原有(you)的ppt文件進(jin)行(xing)對比,才能得出(chu)增量(liang)的數(shu)(shu)據(ju)。

4.2. ppt緩存對象結構

由(you)以上獲得的(de)信息(xi)可得ppt的(de)緩存對象模型結(jie)構(gou),如下:

4.3.VBA 獲取ppt增量數據考慮的實現方法

4.3.1.針對word、excel

  1. 使用錄制宏,記錄下用戶操作,然后傳輸這個宏文件。(即自動生成的VBA代碼)【不可行】
    1. 問題:錄制宏能否實現自動化,使得用戶無感知?
      1. 答:目前未發現錄制宏的自動化功能。
  2. 使用 VBA 代碼,動態獲取 word、excel 的對象,跟原對象進行對比,找出差異進行傳輸。【過程復(fu)雜,繁瑣】
    1. 問題:具體代碼實現有哪些需要考慮的問題?
      1. 答:代碼較為繁瑣,但可以實現。需要評估獲取差異所耗費的時間、資源和直接全量傳輸所耗費的時間、資源。

4.3.2.針對ppt

  1. 使用 VBA 代碼,動態獲取ppt的對象,跟原對象進行對比,找出差異進行傳輸。
    1. 問題:與前面的一樣。

4.4.從官方文檔中尋找比較內容差異相關的API接口

  1. Application.CompareDocuments (word)【不可行(xing)】
    1. 能夠返回有修訂記錄的文檔,不符合要求。
  2. Windows.CompareSideBySideWith method (Excel)【不可(ke)行】
    1. 能夠打開兩個窗口,不符合要求。

4.5.結論

方法3可行(xing)。利用 VBA 編程考(kao)慮能夠(gou)實現Office文件內(nei)容差(cha)異的提取,但是(shi)過程較(jiao)為繁瑣,復雜(za)。

5.綜合結論

1. 方法1:將ppt解壓,變成分散的(de)文(wen)件(jian),對比(bi)各個文(wen)件(jian)的(de)差異,按照文(wen)件(jian)的(de)方式去獲取增量內容。是否可行(xing)?

答:方法1可行(xing)(xing)。將ppt,word,excel文件(jian)解壓(ya),變成分散的文件(jian),對比各個(ge)(ge)文件(jian)的差異(yi),然(ran)后(hou)傳輸這些差異(yi)文件(jian),為(wei)一個(ge)(ge)可行(xing)(xing),且過程不(bu)太復雜(za)的方法。

2. 方法2:利用python,讀取ppt,在python內比較兩個ppt之間的差(cha)異,將差(cha)異部分以某種文(wen)件的形式保存(cun)下來,得到(dao)保存(cun)增(zeng)量數據的文(wen)件。是否可行?

答:方法2可行。但提取(qu)出增量數(shu)據需要(yao)原(yuan)文件和新文件,將兩個文件讀取(qu)到python內存中比較(jiao),代碼需要(yao)循環比較(jiao),過程(cheng)復(fu)雜。

3. 方法3:利用VBA編程,將代碼直(zhi)接插(cha)入到(dao)Office里(li)面,獲取Office的增量數(shu)據。是否可行?

答:方(fang)法(fa)3可(ke)行。利(li)用 VBA 編程考慮能夠(gou)實(shi)現Office文件內(nei)容差異的提取,但是過程較為繁瑣,復雜。

0條評論
0 / 1000
w****n
4文章數
0粉絲數(shu)
w****n
4 文(wen)章(zhang) | 0 粉絲
原創(chuang)

Office調研——獲取Office增量的三種方法的可行性

2023-12-07 02:58:44
23
0

問題提出原因、背景

在高可(ke)用云電腦的項目中,需(xu)要將云電腦中的所有文(wen)(wen)件(jian)(jian)同(tong)步(bu)到另一臺云電腦中,這些(xie)文(wen)(wen)件(jian)(jian)中就有許多是Office文(wen)(wen)件(jian)(jian)。而在實際(ji)運(yun)行中發現,Office源(yuan)文(wen)(wen)件(jian)(jian)的微小改動,都(dou)會使得整個Office文(wen)(wen)件(jian)(jian)都(dou)需(xu)要重新同(tong)步(bu),例如,在Word文(wen)(wen)件(jian)(jian)的末(mo)尾(wei)中,添加一個逗號(hao),整個Word文(wen)(wen)件(jian)(jian)都(dou)發生(sheng)了變化(在磁(ci)盤層面觀察)。這樣同(tong)步(bu)傳輸(shu)時(shi)耗費的時(shi)間和網絡(luo)資源(yuan)都(dou)很大。

因此,需(xu)要調研(yan)Office的緩存機制,了(le)解為何Office的微小改動會導(dao)致整個文件都發生變化,繼而得出該問題的解決辦法。

由(you)上一(yi)(yi)篇“Office調(diao)研——Office的(de)(de)緩存(cun)機(ji)制(zhi)”的(de)(de)文(wen)(wen)章中通過(guo)調(diao)研得出了(le)Office的(de)(de)緩存(cun)、落盤機(ji)制(zhi),并且證明了(le)是(shi)“由(you)于Office軟件在每次保存(cun)中,都(dou)將全量(liang)數據(包括增量(liang))寫入到新的(de)(de)文(wen)(wen)件中,所以從磁盤層面觀察,無論是(shi)多微小的(de)(de)改(gai)(gai)動(dong),都(dou)是(shi)產生(sheng)了(le)一(yi)(yi)個新文(wen)(wen)件”,導致Office的(de)(de)微小改(gai)(gai)動(dong)會導致整個文(wen)(wen)件都(dou)發生(sheng)變化。

本篇繼續調(diao)研上一篇“Office調(diao)研——Office的(de)緩存機制”的(de)文章中提出(chu)的(de)獲取Office增(zeng)量(liang)的(de)三(san)種方法(fa)是否可(ke)行。

1.問題描述

  1. 方法1:將ppt解壓,變成分散的文件,對比各個文件的差異,按照文件的方式去獲取增量內容。是否可行?
  2. 方法2:利用python,讀取ppt,在python內比較兩個ppt之間的差異,將差異部分以某種文件的形式保存下來,得到保存增量數據的文件。是否可行?
  3. 方法3:利用VBA編程,將代碼直接插入到Office里面,獲取Office的增量數據。是否可行?

2.方法1:將ppt解壓,變成分散的文件,對比各個文件的差異

2.1.對 word、excel、ppt解壓后(zip 解壓)的文件結構,如下:

Word excel ppt

2.2.修改word內容,記錄word解壓后的文件的改變情況

修改前文件大小 修改后文件大小
text001.docx :570KB
解壓后:604KB
圖片:557KB
其他:43.9KB
text001.docx :1.095MB
解壓后:1.10MB
圖片:1050KB
其他:45.7KB
其中新增圖片:525KB

若(ruo)按照docx文件傳輸,則(ze)需要傳輸 1.095 MB

若按照解(jie)壓后的文件傳(chuan)(chuan)輸(shu),則至少(shao)需要傳(chuan)(chuan)輸(shu) 526.317KB ,最多需要傳(chuan)(chuan)輸(shu) 1.10MB

2.3.修改excel內容,記錄excel解壓后的文件的改變情況

修改前文件大小 修改后文件大小
   

若(ruo)按(an)照excel文件傳輸(shu),則需要傳輸(shu) 9KB

若按照解壓后(hou)的文件傳輸,則至少需要(yao)傳輸 0.2KB ,最(zui)多(duo)需要(yao)傳輸 28KB

2.4.修改ppt內容,記錄ppt解壓后的文件改變情況

修改前文件大小 修改后文件大小

若(ruo)按照excel文(wen)件傳輸,則(ze)需要傳輸 346KB

若按照解(jie)壓后(hou)的(de)文件傳輸(shu),則至少(shao)需(xu)要傳輸(shu) 11KB ,最多需(xu)要傳輸(shu) 407KB

2.5.使用 beyond compare 工具對比文件前后改變情況

Word:增加了兩行文字,增加了一張圖片

Excel:增加了兩個單(dan)元(yuan)格內(nei)容(rong)。

ppt:第一(yi)張幻燈片調整了文字框,沒有(you)增(zeng)加文字。

新增(zeng)了2,3,4,5,6幻燈(deng)片,幻燈(deng)片內容(rong)都為(wei)文字

解壓(ya)后傳(chuan)輸 26185 字節,約 25.57KB

pptx傳輸 353780 字節,約 345.49KB

傳輸(shu)量約為原本的(de) 7.4 01%

2.6.結論

方法(fa)1可行。將ppt,word,excel文件(jian)解壓,變(bian)成分散(san)的(de)(de)文件(jian),對比各個文件(jian)的(de)(de)差異,然(ran)后傳輸這些差異文件(jian),為(wei)一個可行,且過程不太復雜的(de)(de)方法(fa)。

3.方法2:利用python,讀取ppt,在python內比較兩個ppt之間的差異,將差異部分以某種文件的形式保存下來,得到保存增量數據的文件

3.1.以ppt文件為例,利用python-pptx庫實現獲取ppt的增量數據,編寫demo代碼

demo代碼:

import pathlib
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.shapes import MSO_SHAPE_TYPE
# 借用openpyxl的單位轉換
from openpyxl.utils.units import EMU_to_pixels as e2p

def output_diff_dict(diff_dict):
	print(f'========== print diff dict ==========')
	for key, value in diff_dict.items():
		print(f'key = {key} | value = {value} | type = {type(value)}')

path = list(pathlib.Path.cwd().parents)[1].joinpath('D:\\xxxxx')
img_out_path = path.joinpath('ppt_out_images')
txt_out_path = path.joinpath('ppt_notes.txt')

def create_new_ppt(origin_ppt, diff_dict):
	for key,value in diff_dict.items():
		key_temp = key.split(",")
		key_len = len(key_temp)
		
		# 添加頁
		# todo
		if key_len == 1:
			if value == 'NULL':
				origin_ppt.slides._sldIdLst.remove[int(key_temp[0])] 
			else:
				# todo
				print('need add slides')
		
		# 添加 shape
		# todo
		if key_len == 2:
			shapes_temp = origin_ppt.slides[int(key_temp[0])].shapes
			if value == 'NULL':
				# todo
				print('need delete shape')
			else:
				if (value.shape_type == MSO_SHAPE_TYPE.PICTURE):
					#shapes_temp.add_picture(value, left = value.left, top = value.top)
					
					# 獲取二進制字符流
					imdata = value.image.blob
					# 判斷文件后綴類型
					imagetype = value.image.content_type
					typekey = imagetype.find('/') + 1
					imtype = imagetype[typekey:]
					
					# 圖片生成
					image_file = ".\\pic001" + "." + imtype

					file_str=open(image_file,'wb')
					file_str.write(imdata)
					file_str.close()
					
					shapes_temp.add_picture(image_file, left = value.left, top = value.top, width=value.width, height=value.height)
				elif (value.has_text_frame):
					new_text = shapes_temp.add_textbox(left=value.left, top=value.top, width=value.width, height=value.height).text_frame
					new_text.paragraphs[0].text = value.text_frame.text
					
				else:
					print('need add shape')
		
		# 修改 shape
		# todo
		
		if key_len == 3:
			slide_layouts_temp = origin_ppt.slide_master.slide_layouts
			shape_temp = origin_ppt.slides[int(key_temp[0])].shapes[int(key_temp[1])]
			# text 類型
			if key_temp[2] == 'text':
				if value == 'NULL':
					#todo
					print('need delete text')
				else:
					shape_temp.text_frame.text = value
			# image 類型
			if key_temp[2] == 'image':
				if value == 'NULL':
					print('need delete image')
				else:
					shape_temp.image = value
				
	print('save ppt.')
	origin_ppt.save("text003.pptx")

# 獲取到對象
in_path1 = path.joinpath('test001.pptx')
prs1 = Presentation(in_path1)
in_path2 = path.joinpath('test002.pptx')
prs2 = Presentation(in_path2)

# 存儲位置 + 內容
diff_dict = {}

# 比較頁數,存儲不同的整頁
print(f'========== compare slide len ==========')
slide1_len = len(prs1.slides)
slide2_len = len(prs2.slides)
# EMU單位,1 Pixel = 9525 EMU
w, h = prs1.slide_width, prs1.slide_height
print(f'ppt1 總共 {slide1_len} 頁,頁寬 {e2p(w)} px,頁高 {e2p(h)} px')
w, h = prs2.slide_width, prs2.slide_height
print(f'ppt2 總共 {slide2_len} 頁,頁寬 {e2p(w)} px,頁高 {e2p(h)} px')

less_slide_len = slide1_len
if(slide1_len != slide2_len):
	if(slide1_len < slide2_len):
		for i in range(slide1_len, slide2_len):
			diff_dict[f"{i}"] = prs2.slides[i]
	else:
		less_slide_len = slide2_len
		for i in range(slide2_len, slide1_len):
			diff_dict[f"{i}"] = 'NULL'

# 比較每頁,存儲每頁不同
for i in range(less_slide_len):
	print(f'========== compare slide[{i}] ==========')
	slide1 = prs1.slides[i]
	slide2 = prs2.slides[i]
	slide_key = f"{i}"
	
	# 比較每頁里面的形狀shape,shape包含ppt里面一切可視元素
	shape1_len = len(slide1.shapes)
	shape2_len = len(slide2.shapes)
	less_shape_len = shape1_len
	
	if(shape1_len != shape2_len):
		if(shape1_len < shape2_len):
			for j in range(shape1_len, shape2_len):
				shape_key = slide_key + f",{j}"
				diff_dict[shape_key] = slide2.shapes[j]
		else:
			less_shape_len = shape2_len
			for j in range(shape2_len, shape1_len):
				shape_key = slide_key + f",{j}"
				diff_dict[shape_key] = 'NULL'

	print(f'ppt1 總共 {shape1_len} 個shape')
	print(f'ppt2 總共 {shape2_len} 個shape')
	
	# 比較每個形狀
	for j in range(less_shape_len):
		print(f'========== compare shape[{j}] ==========')
		shape1 = slide1.shapes[j]
		shape2 = slide2.shapes[j]
		shape_key = slide_key + f",{j}"
		
		# 比較shape里的文本
		if (shape1.has_text_frame) :
			text_key = shape_key + ",text"
			
			if (shape2.has_text_frame):
				text1 = shape1.text_frame.text
				text2 = shape2.text_frame.text
				print(f'ppt1 = {text1}')
				print(f'ppt2 = {text2}')
				if( text1 != text2):
					print(f'text different.')
					diff_dict[text_key] = text2
			else:
				print(f'ppt2 has not text.')
				diff_dict[text_key] = 'NULL'
		
		# 比較shape里的圖片
		if (shape1.shape_type == MSO_SHAPE_TYPE.PICTURE):
			image_key = shape_key + ",image"
			
			if (shape2.shape_type == MSO_SHAPE_TYPE.PICTURE):
				img1 = shape1.image
				img2 = shape2.image
				if( img1 != img2):
					print(f'image different.')
					diff_dict[image_key] = img2
			else:
				print(f'ppt2 has not image.')
				diff_dict[image_key] = 'NULL'
		
output_diff_dict(diff_dict)

create_new_ppt(prs1, diff_dict)

3.2.結論

方法(fa)2可行。但提取(qu)出增量(liang)數據需要原文件(jian)和新文件(jian),將兩個文件(jian)讀取(qu)到(dao)python內存中比(bi)較(jiao),代(dai)碼需要循環比(bi)較(jiao),過程復雜(za)。

4.方法3:利用VBA編程,將代碼直接插入到Office里面,獲取Office的增量數據

4.1.以ppt文件為例,調研VBA編程可以獲取到ppt對象模型中的全量數據,還是增量數據。

經(jing)過調(diao)研、代(dai)碼實踐可知,VBA 編程(cheng)中(zhong)獲取(qu)的 ppt 對(dui)象(xiang)數(shu)據為全量數(shu)據,證明如下:

1. 利用VBA代(dai)碼訪問打(da)開的(de) ppt 中的(de)對象,檢查其提取(qu)該對象的(de)文本內(nei)容。

在未保存(cun)時(shi),提取的結果(guo)為(wei)該對象(xiang)的所有文本(不區分原有和新增)

在(zai)按下 “CTRL+S” 保(bao)存(cun)時,提取的(de)結果依然為該對象的(de)所(suo)有文本(不(bu)區分原有和新增)

2. 對(dui)(dui)官(guan)方網站提供的(de)(de)(de)API接口進行查(cha)詢(xun),未發現專門存(cun)(cun)儲增量(liang)數(shu)據的(de)(de)(de)對(dui)(dui)象(xiang)。從API文(wen)檔中(zhong)可以(yi)看(kan)出,ppt在內存(cun)(cun)中(zhong)是以(yi)一(yi)個個對(dui)(dui)象(xiang)進行存(cun)(cun)儲的(de)(de)(de),該(gai)對(dui)(dui)象(xiang)包(bao)含了ppt的(de)(de)(de)所有信息,用戶(hu)在編輯ppt時,實際上就在動態(tai)地(di)修改(gai)內存(cun)(cun)中(zhong)的(de)(de)(de)對(dui)(dui)象(xiang)(對(dui)(dui)象(xiang)中(zhong)存(cun)(cun)儲的(de)(de)(de)數(shu)據總是原有+增量(liang),即最新(xin)的(de)(de)(de)全量(liang)數(shu)據),用戶(hu)敲下CTRL+S時,系統(tong)對(dui)(dui)內存(cun)(cun)中(zhong)的(de)(de)(de)所有ppt對(dui)(dui)象(xiang)進行落(luo)盤(pan)存(cun)(cun)儲,并覆蓋原來的(de)(de)(de)ppt文(wen)件(jian),形成新(xin)的(de)(de)(de)ppt文(wen)件(jian)。

3. 即使ppt在緩存中把(ba)原有的(de)(de)(de)數(shu)據(ju)和(he)增(zeng)量的(de)(de)(de)數(shu)據(ju)分開存儲了,在VBA層面也是不可知的(de)(de)(de),因為VBA是調用ppt的(de)(de)(de)API進行訪問,API中沒有對增(zeng)量數(shu)據(ju)的(de)(de)(de)訪問,則(ze)VBA無法獲(huo)取增(zeng)量數(shu)據(ju)。

4.1.1.結論

由(you)以上3點可以推斷,利用(yong)VBA工具也(ye)只能先提取出ppt的全(quan)量數(shu)據,再與原有(you)的ppt文(wen)件進行對比(bi),才能得出增量的數(shu)據。

4.2. ppt緩存對象結構

由(you)以上獲得的(de)信(xin)息可得ppt的(de)緩存對(dui)象模(mo)型結構,如(ru)下:

4.3.VBA 獲取ppt增量數據考慮的實現方法

4.3.1.針對word、excel

  1. 使用錄制宏,記錄下用戶操作,然后傳輸這個宏文件。(即自動生成的VBA代碼)【不(bu)可行】
    1. 問題:錄制宏能否實現自動化,使得用戶無感知?
      1. 答:目前未發現錄制宏的自動化功能。
  2. 使用 VBA 代碼,動態獲取 word、excel 的對象,跟原對象進行對比,找出差異進行傳輸。【過程復雜,繁瑣】
    1. 問題:具體代碼實現有哪些需要考慮的問題?
      1. 答:代碼較為繁瑣,但可以實現。需要評估獲取差異所耗費的時間、資源和直接全量傳輸所耗費的時間、資源。

4.3.2.針對ppt

  1. 使用 VBA 代碼,動態獲取ppt的對象,跟原對象進行對比,找出差異進行傳輸。
    1. 問題:與前面的一樣。

4.4.從官方文檔中尋找比較內容差異相關的API接口

  1. Application.CompareDocuments (word)【不可(ke)行(xing)】
    1. 能夠返回有修訂記錄的文檔,不符合要求。
  2. Windows.CompareSideBySideWith method (Excel)【不可行(xing)】
    1. 能夠打開兩個窗口,不符合要求。

4.5.結論

方(fang)法3可行。利(li)用 VBA 編程考(kao)慮能(neng)夠實現(xian)Office文件內容差異的提取,但(dan)是過程較(jiao)為繁瑣,復(fu)雜(za)。

5.綜合結論

1. 方(fang)法1:將ppt解壓,變成分散的文件,對比各個文件的差異,按照(zhao)文件的方(fang)式去獲取增量內容。是(shi)否可行(xing)?

答(da):方法1可行(xing)。將ppt,word,excel文(wen)件(jian)(jian)解(jie)壓,變(bian)成分散的(de)文(wen)件(jian)(jian),對比各個文(wen)件(jian)(jian)的(de)差異,然(ran)后(hou)傳輸這些差異文(wen)件(jian)(jian),為一個可行(xing),且過程不太復(fu)雜的(de)方法。

2. 方(fang)法2:利用(yong)python,讀取ppt,在python內比較兩(liang)個ppt之間的差異(yi),將差異(yi)部分以某(mou)種文件的形式(shi)保(bao)存(cun)下來,得到(dao)保(bao)存(cun)增量數據的文件。是否可行?

答(da):方法2可行。但提取(qu)出增量數據(ju)需要原文件(jian)和新(xin)文件(jian),將兩(liang)個文件(jian)讀取(qu)到python內(nei)存中比(bi)較(jiao),代(dai)碼(ma)需要循環(huan)比(bi)較(jiao),過(guo)程復(fu)雜。

3. 方法3:利用VBA編程,將代碼(ma)直接插入到Office里面,獲取Office的增量數(shu)據。是(shi)否可行?

答:方法3可(ke)行。利(li)用 VBA 編程(cheng)(cheng)考慮(lv)能夠實現Office文件內容(rong)差異(yi)的提取,但(dan)是過程(cheng)(cheng)較為(wei)繁瑣,復雜。

文章來自個人專欄
文章(zhang) | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0