摘" 要: 針對信息化系統導出的電子表格在打印時不能直觀顯示分頁效果,需要人工排版的問題,提出一種自動化分頁排版算法,能夠預測出表格的分頁結果,并根據結果進行自動化排版。通過實驗驗證,該方法在大部分常見情況下,均表現出不錯的適應性和健壯性,節省了人工排版成本。
關鍵詞: 信息化系統; 電子表格; 自動化; 打印; 排版
中圖分類號:TP391.1" " " " " 文獻標識碼:A" " "文章編號:1006-8228(2023)12-189-05
Research on automatic paging and typesetting algorithm for information
system table export and printing
Tan Zaowen
(Academy of National Space Planning, Hualan Design (Group) Co., LTD, Nanning, Guangxi 530011, China)
Abstract: Aiming at the problem that the spreadsheets exported from the information system cannot display the paging effect visually and needs manual typesetting, an automatic paging typesetting algorithm is proposed, which can predict the paging results of the tables and automatically typeset them according to the results. The experimental results show that this method has good adaptability and robustness in most common situations and saves the cost of manual typesetting.
Key words: information system; spreadsheet; automation; printing; typesetting
0 引言
隨著計算機技術的飛速發展,互聯網、大數據、云計算、人工智能等新興技術不斷涌現,推動了企業業務流程的信息化和智能化發展[1]。許多企業已經將各類信息化系統廣泛應用于日常的生產經營管理過程中,對企業發展起到了重要的輔助作用。信息化系統為了增強對實際業務的關聯性、適應性,通常具有將系統的成果、統計等數據導出的能力。電子表格是辦公自動化的重要組成部分,因其具有直觀的界面、出色的計算功能和圖表工具,經常用來當作數據可視化、數據處理的工具[2-3],是承載各類導出數據的極佳選擇。在部分使用場景中,導出的電子表格需要進行打印,以滿足查看、上會、歸檔等需求。然而,不同于文檔、幻燈片等能夠直接在界面上以分頁進行顯示的辦公軟件,電子表格軟件的界面僅顯示為網狀排列的連續單元格。在對電子表格進行分頁打印時,通常需要手動對單元格的行高、列寬進行排版調整[4],如果不對表格進行排版,打印出來的內容將會非常不美觀。面對內容龐大的電子表格,消耗在排版上的時間與精力將成倍上升。
不少學者通過多種方式對電子表格打印排版進行研究,并取得一定程度的效果。王志軍提出借助Word文檔軟件實現電子表格的分欄打印,用于解決一些列數較少而行數很多的電子表格打印效果不美觀的問題[5]。姚文連通過在電子表格中添加輔助列,并對表格數據進行轉置的方式,實現電子表格排版優化[6]。平淡針對電子表格包含有圖片的情況,提出先將圖片的路徑放入單元格,調整好單元格尺寸后再利用公式批量導入,簡化了電子表格排版流程[7]。
以上方法雖然可以在一定程度上減少電子表格排版所消耗的時間和精力,但依然具有局限性,操作上仍然需要人工的參與。使用自動化方式對導出的電子表格進行分頁排版處理的需求日益迫切。
電子表格的打印效果受紙張尺寸、頁邊距、合并單元格、打印標題等因素影響,本文針對這些影響因素,提出一種信息化系統導表打印需求下的分頁排版算法,該算法可直接集成至信息化系統的導表模塊,也可作為獨立通用工具使用。通過實驗驗證,該算法能夠很好地解決電子表格分頁打印時的排版問題。
1 算法原理與過程
排版算法的原理是通過一系列步驟,預測出單元格將會出現在的分頁,根據單元格分頁的預測結果,調整工作表的列寬及行高,使得每個分頁的單元格都恰好占滿整個分頁打印空間,并盡量完整顯示每個單元格自身的內容。
該算法的過程主要有五步:
⑴ 通過紙張尺寸、頁邊距等參數,計算出每個打印分頁能夠容納單元格的剩余空間。
⑵ 根據打印空間,調整工作表的列寬,使得工作表的所有列都能夠在一個分頁中顯示。
⑶ 根據列寬的調整結果,計算出工作表能夠完整顯示單元格內容時,每行的最小行高。
⑷ 根據最小行高,計算預測出每行的所在的分頁。
⑸ 根據分頁的預測結果,調整工作表的行高,使得每個分頁的行以及單元格都恰好占滿整個分頁打印空間。
算法以工作表的所有列能夠合適地排版在一個分頁內的情況為例,對于工作表的列數量過多而不能排版在一個分頁內的情況,可以參照處理工作表的行的方式進行處理,本文不進行額外贅述。
1.1 計算分頁打印空間
算法1 計算分頁打印空間
輸入:紙張寬度[W'p],紙張高度[H'p],上頁邊距[Mt],下頁邊距[Mb],左頁邊距[Wl],右頁邊距[Wr]。
輸出:分頁寬度[Wp],分頁高度[Hp]。
⑴ 頁面縱向打印時,[Wp=W'p-Wl-Wr×1257.33],[Hp=H'p-Mt-Mb×32]。
⑵ 頁面橫向打印時,[Wp=H'p-Wl-Wr×1257.33],[Hp=W'p-Mt-Mb×32]。
算法1展示了計算分頁打印空間的過程。
根據表格頁面打印方向,選擇相應的頁邊距參數,計算出分頁寬度[Wp]和分頁高度[Hp]。
其中,[Wp]的單位為32pixel(單位像素的32倍),1257.33是cm(厘米)與32piexl的單位轉換因子。[Hp]的單位為pound(磅),32是厘米與磅的單位轉換因子,工作表的行高的最小調整單位是0.75磅,因此分頁高度應為0.75的整數倍。
1.2 調整列寬
算法2 調整工作表列寬
輸入:分頁寬度[Wp]。
輸出:無。
⑴ 計算工作表原始列寬[Ww=i=0nW'i],[W'i]為工作表第[i]列的原始列寬。
⑵ 計算調整比例[s=WpWw]。
⑶ 循環工作表所有列,對每列[i]調整列寬為[Wi=sW'i]。
算法2展示了調整工作表列寬的過程。
其中,[s]表示把工作表的全部列恰好填滿打印空間所需要調整的比例;[Wi]表示調整后的工作表第[i]列的列寬。
1.3 計算最小行高
算法3 計算工作表每行的最小行高
輸入:分頁寬度[Wp]。
輸出:工作表每行的最小行高[Hi]。
⑴ 循環計算獨立單元格[ci,j]完整顯示其內容所需的最小行高[Hi,j=hwls],[hw]為文字高度,[l]為內容行數,[s]為行間距。
⑵ 計算包含有合并單元格的行[i]的最小行高[H''i=maxMihwlsq-p+1,i∈[p,q]],[Mi]為包含有行[i]的合并單元格集合,[p]、[q]分別為合并單元格的起始、結束行序號。
⑶ 循環所有行[i],列[j]。
① 初始化[Hi←0];
② 若[Hi,jgt;Hi],則更新[Hi←Hi,j];
③ 若[H''igt;Hi],則更新[Hi←H''i]。
算法3展示了計算工作表每行的最小行高的過程。
[Hi,j]為單元格列寬確定的情況下,完整顯示單元格內容(自動換行)所需的最小高度。其中,文字高度由字號、字體、樣式(是否加粗、斜體等)共同決定,內容行數由單元格列寬、文字寬度、文字間距共同決定。
合并單元格會對其所在的行的最小行高產生影響,其列寬為所包含的所有列的列寬之和。計算得到合并單元格的最小行高將會平均分攤到其所包含的所有行的最小行高,[H''i]即為所求。其中,[p]為該合并單元格的起始序號、[q]為該合并單元格的結束序號。
1.4 計算打印分頁
算法4 計算打印分頁列表
輸入:分頁高度[Hp],工作表每行的最小行高[Hi],打印標題起始行序號[p],打印標題結束行序號[q]。
輸出:打印分頁列表[P]。
⑴ 計算打印標題行高[Ht=i=pqHi,?Htlt;Hp]。
⑵ 初始化當前分頁高度[H'p←Hp],臨時頁積累高度[h←0],打印分頁列表[P←?],臨時當前分頁[p'←?]。
⑶ 循環所有行序號[i],對應的行為[ri]。
① 如果[i∈[p,q]],則判斷打印標題是否能完全加入當前頁。
(a) 如果為真,則[p'←p'+{ri|i∈[p,q]}],[H'p←Hp-Ht],行序號[i]跳轉至[q]后繼續循環。
(b) 如果為否,則[P←P+p'],[p'←{ri|i∈[p,q]}],[H'p←Hp-Ht],[h←0],行序號[i]跳轉至[q]后繼續循環。
② 如果[i?[p,q]],則查找[i]為起始序號的合并單元格列表[Mi],若存在,將列表以行高倒序排序;循環判斷列表[Mi],找出第一個高度不大于[H'p]的合并單元格[M'i],其結束行序號為[r],行高為[H'm]。
(a) 如果[?M'i],則[h←h+H'm]。
如果此時[h≤H'p],則[p'←p'+{rj|j∈[i,r]}],行序號[i]跳轉至[r]后繼續循環。
如果此時[hgt;H'p],則[P←P+p'],[p'←{rj|j∈[i,r]}],[h←H'm],行序號[i]跳轉至[r]后繼續循環。
(b) 如果[?M'i],則忽略,判斷[Hi]與[H'p]的大小。
如果[Hi≤H'p],則[h←h+Hi];如果此時[hlt;H'p],則[p'←p'+{ri}];反之,則[P←P+p'],[p'←{ri}],[h←Hi];結束本輪循環。
如果[Higt;H'p],則[P←P+p'+p'',p''={ri}],[p'←?],[h←0];結束本輪循環。
算法4展示了計算打印分頁列表的過程。
如果[ri]的行高不大于當前分頁高度[H'p],則根據其行高與當前頁剩余高度的比較結果,加入當前頁或下一頁;反之,則說明行高超過打印分頁的高度限制,將其加入下一頁,后續會強制壓縮其高度。
生成打印分頁列表[P]為二維數組,第一維為工作表打印時的分頁,第二維為分頁包含的行。
1.5 調整行高
算法5 根據分頁列表調整行高
輸入:打印分頁列表[P],分頁高度[Hp],打印標題行高[Ht],工作表每行的最小行高[Hi],打印標題起始行序號[p],打印標題結束行序號[q]。
輸出:無。
⑴ 初始化當前分頁高度[H'p←Hp];
⑵ 循環分頁列表[P]的所有分頁,分頁序號為[h],當前頁記為[Ph],當前頁[Ph]內的所有行記為[{ri|ri∈Ph}],[i]為行序號。
① 如果[i∈[p,q]],則[H'p←Hp-Ht],[Ph←]
[{ri|ri∈Ph,i?[p,q]}];
② 計算[Ph]所有行的行高之和[Hh=iHi,ri∈Ph];
③ 計算調整比例[s=H'pHh];
④ 循環[Ph]內所有行[ri]。
(a) 初始化分頁積累高度[h←0];
(b) 如果[ri]不為[Ph]的最后一行,則[Hi←His],[h←h+Hi];
(c) 否則,[Hi←H'p-h]。
算法5展示了根據分頁列表調整行高的過程。
遍歷分頁列表的所有分頁,計算分頁[Ph]所有行的行高之和[Hh],并計算縮放比[s];特別的,[Ph]存在打印標題時,將分頁標題的行高[Ht]從分頁高度[H'p]中減去。
遍歷分頁[Ph]內的所有行[ri],對于分頁的非最后一行,根據縮放比調整行高;對于分頁的最后一行,為避免運算帶來的誤差,將根據當前分頁剩余可用高度進行調整。
2 算法實現
算法使用Java語言實現,所屬類的部分代碼如算法6所示:
算法6 排版算法所屬類的部分代碼
publicabstract class AbstractExcelGeneratorlt;Datagt; {
Workbook generate(Data data);
void printAdaption(Workbook wb, PrintTemplate pt) {
// ...
for (Sheet sheet : wb) {
pageSize=calLimitedPageSize(sheet, width, height,
top, bottom, left, right, landscape);
resizePrintColumn(pageWidth);
minRHList = calMinRowHeightList(sheet);
pageList = pageSegmentation(minRHList,
pageHeight, repeatingRows);
pageAdjustment(pageList, pageHeight,
repeatingRows);
}
}
boolean writeToFile(Workbook wb, File file);
boolean writeToOS(Workbook wb, OutputStream os);
}
該類為抽象類,用于構造表格生成器的通用模板,具體業務的表格生成器可繼承自該抽象類。
模板首先使用generate方法,根據數據內容生成電子表格對象。然后對電子表格對象的每個子表sheet使用printAdaption方法即本文的分頁排版算法,對表格進行排版調整,其中:
⑴ calLimitedPageSize:根據打印頁面尺寸、頁邊距、打印方向等參數,計算出分頁打印空間。
⑵ resizePrintColumn:根據得出的分頁寬度,計算表格列的縮放比,調整表格的列寬。
⑶ calMinRowHeightList:根據前兩步得出的結果,結合單元格內容的字號、字體、樣式等參數,計算出表格每行的最小行高。
⑷ pageSegmentation:根據得出的最小行高,對表格分頁進行預測,并生成分頁列表。
⑸ pageAdjustment:根據得出的分頁列表,調整表格每行的行高,完成排版。
最后,經過排版調整的電子表格對象,根據用途的不同,可以使用writeToFile方法將表格輸出到文件,或使用writeToOS方法將表格輸出到輸出流。
3 實驗驗證
實驗使用本文的算法實現,將數據轉換成電子表格,并導出為xlsx文件。使用Microsoft365 Excel 2302版本軟件將xlsx文件打開,并將其打印成pdf文件進行測試,以模擬工作中對信息化系統導出的電子表格進行分頁打印的情況。為了模擬實際工作中使用電子表格,生成的電子表格將包含文字、數字、百分比等單元格,并存在大段文字、合并單元格、打印標題等復雜內容,用于測試排版算法面對大部分情況下的適用能力。
圖1展示了電子表格使用排版算法前的打印效果。電子表格未進行任何調整,可以看出此時工作表未占滿分頁的橫向、縱向打印空間,并且每個分頁的縱向排版并不整齊。
圖2展示了電子表格使用排版算法后的打印效果。可以看出此時工作表已占滿分頁的橫向、縱向打印空間,并且每個分頁的縱向排版整齊一致,單元格內容也能完整顯示。
更具體的,包含合并單元格的行能夠被優先整合并排版在一個分頁內,使得表格內容的展示更具有關聯性,如圖3所示。
當完整的合并單元格所包含的內容無法在一個分頁中顯示時,將分割合并單元格,根據次級合并單元格或者單行進行排版,優先保證內容顯示的完整性,并盡量滿足內容顯示的關聯性。如圖4所示。
還可以將每個分頁單元格的總尺寸調整至相同,并且填滿頁邊距以外的打印空間。對于內容通常較少的最后一個分頁也能有相同效果,如圖5所示。
同時,算法還考慮了表格存在標題的情況,為分頁的標題單元格預留了打印空間。
通過本實驗,能夠證明本文提出的分頁排版算法可以很好地解決信息化系統導出的電子表格進行打印時的分頁排版問題,在保證內容完整性和關聯性的前提下,最大程度地利用打印空間,使得打印結果更整齊、美觀。
4 結束語
綜上所述,本文系統地研究出了一種信息化系統導表打印需求下的分頁排版算法。該方法能夠解決信息化系統導出的電子表格在打印時,單元格所屬的分頁不直觀的情況,并自動對電子表格進行排版,節省了人工消耗在電子表格分頁排版上的時間與精力。該算法在面對大部分常見情況時,均表現出不錯的適應性、健壯性。
但算法目前還未考慮到電子表格含有圖片或公式等內容的情況。在后續的工作中,還將對上述內容進行補充研究,以擴大算法的適用范圍。
參考文獻(References):
[1] 趙欣悅.國企集團財務信息化建設中存在的問題以及對策
建議[J].中小企業管理與科技,2023,No.702(9):158-160.
[2] 徐玲.Excel在高中物理實驗數據處理中的應用研究[D].
桂林:廣西師范大學,2018.
[3] 王瑞,郝建偉.公路工程試驗檢測報告編制中Microsoft
Excel的巧用[J].工程建設與設計,2022(21):124-126.
[4] 許艷云.Word和Excel辦公文檔快速排版技巧淺談[J].電腦
知識與技術,2011,7(14):3455-3456.
[5] 王志軍.借助Word實現Excel工作表的分欄打印[J].電腦
知識與技術(經驗技巧),2018(6):41-42.
[6] 姚文連.巧借Excel輔助列為數據表格整容[J]電腦迷,2011,
No.201(14):60.
[7] 平淡.先導照片再排版Excel一步到位[J].電腦愛好者,2017,
No.517(6):40-41.