利用Jacob將Excel轉(zhuǎn)換PDF的問(wèn)題匯總
前言
好久不見(jiàn),分享一個(gè)近期在項(xiàng)目開(kāi)發(fā)中遇到的一個(gè)新問(wèn)題,關(guān)于使用easyexcel生成Excel,并且使用jacob轉(zhuǎn)換成PDF的需求,最開(kāi)始的時(shí)候在網(wǎng)上找了一些相關(guān)的教程,經(jīng)過(guò)篩選之后發(fā)現(xiàn)還是使用jacob調(diào)用office軟件來(lái)進(jìn)行轉(zhuǎn)換是最可靠的。然后就和大家出了一篇關(guān)于使用jacob將Excel文件轉(zhuǎn)換PDF的教程,Excel轉(zhuǎn)換PDF兩種方法總結(jié)
但是后來(lái)我在實(shí)踐操作中發(fā)現(xiàn),原來(lái)的代碼只能實(shí)現(xiàn)基本轉(zhuǎn)換,對(duì)于一些較為復(fù)雜或數(shù)據(jù)量較大的代碼就會(huì)出現(xiàn)一些問(wèn)題,
使用Jacob轉(zhuǎn)換的基本操作和網(wǎng)上其他的教程基本類似,在這里我主要記錄一下我在轉(zhuǎn)換中遇到的一些問(wèn)題,以及在最基本的Excel轉(zhuǎn)PDF的代碼的基礎(chǔ)上增加的一些東西。
問(wèn)題一、Excel數(shù)據(jù)列較多時(shí),PDF中列打印不全,
對(duì)于一些比較復(fù)雜的數(shù)據(jù)表,數(shù)據(jù)列非常的多,有時(shí)候按照正常設(shè)置在轉(zhuǎn)換PDF的時(shí)候,經(jīng)常會(huì)出現(xiàn)列顯示不全,部分列溢出的情況。 針對(duì)這個(gè)問(wèn)題,可以在Excel轉(zhuǎn)換PDF中做一些設(shè)置。其中設(shè)置項(xiàng)及其參數(shù)可以在如下的代碼中設(shè)置:
Dispatch.put(value, "key",);
在這里我設(shè)置了縮放、縱向打印、行列等屬性來(lái)解決上面的問(wèn)題,這些設(shè)置可以在下面的代碼中看到,大家可以直接在自己的轉(zhuǎn)換代碼對(duì)應(yīng)位置做同樣的設(shè)置。當(dāng)然我下面的代碼是直接配置好的,可以直接復(fù)制使用。
轉(zhuǎn)換功能:
package com.gyg.util; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; import com.spire.xls.FileFormat; import com.spire.xls.Workbook; import com.spire.xls.Worksheet; import lombok.extern.slf4j.Slf4j; /** * @author YunGang.Guo * @date 2022/01/05 16:44 **/ @Slf4j public class ExcelToPDFUtil { /** * 使用jacob實(shí)現(xiàn)excel轉(zhuǎn)PDF * * @param inputFilePath 導(dǎo)入Excel文件路徑 * @param outputFilePath 導(dǎo)出PDF文件路徑 */ public static void jacobExcelToPDF(String inputFilePath, String outputFilePath) { ActiveXComponent ax = null; Dispatch excel = null; try { ComThread.InitSTA(); ax = new ActiveXComponent("Excel.Application"); ax.setProperty("Visible", new Variant(false)); //禁用宏 ax.setProperty("AutomationSecurity", new Variant(3)); Dispatch excels = ax.getProperty("Workbooks").toDispatch(); Object[] obj = { inputFilePath, new Variant(false), new Variant(false) }; excel = Dispatch.invoke(excels, "Open", Dispatch.Method, obj, new int[9]).toDispatch(); //獲取到sheets的集合對(duì)象 Dispatch sheets = Dispatch.get(excel, "sheets").toDispatch(); //獲取到總表數(shù) int count = Dispatch.get(sheets, "count").changeType(Variant.VariantInt).getInt(); for (int i = 1; i <= count; i++) { //獲取到sheet頁(yè) Dispatch sheet = Dispatch.invoke(sheets, "Item", Dispatch.Get, new Object[]{i}, new int[1]).toDispatch(); Dispatch page = Dispatch.get(sheet, "PageSetup").toDispatch(); //是否設(shè)置區(qū)域打印 Dispatch.put(page, "PrintArea", false); //設(shè)置橫向打印還是縱向打印 Dispatch.put(page, "Orientation", 2); //設(shè)置縮放,值為100或false Dispatch.put(page, "Zoom", false); //所有行為一頁(yè) Dispatch.put(page, "FitToPagesTall", false); //所有列為一頁(yè)(1或false) Dispatch.put(page, "FitToPagesWide", 1); log.info("sheet頁(yè)[" + i + "]設(shè)置成功,"); } //轉(zhuǎn)換格式 Object[] obj2 = { //PDF格式等于0 new Variant(0), outputFilePath, //0=標(biāo)準(zhǔn)(生成的PDF圖片不會(huì)模糊),1=最小的文件 new Variant(0) }; Dispatch.invoke(excel, "ExportAsFixedFormat", Dispatch.Method, obj2, new int[1]); } catch (Exception e) { e.printStackTrace(); throw e; } finally { if (excel != null) { Dispatch.call(excel, "Close", new Variant(false)); } if (ax != null) { ax.invoke("Quit", new Variant[]{}); ax = null; } ComThread.Release(); } } }
問(wèn)題二、大量數(shù)據(jù)時(shí),PDF頁(yè)模糊解決
在平常項(xiàng)目中需要導(dǎo)出的Excel表中的數(shù)據(jù)量是非常大的,對(duì)于這種情況,一般在轉(zhuǎn)換的PDF中一張表對(duì)應(yīng)一頁(yè)是不太可能的。但是Jacob轉(zhuǎn)換時(shí)默認(rèn)就是讓一個(gè)表在一頁(yè)上,這樣就導(dǎo)致了數(shù)據(jù)會(huì)被縮放的特別小,導(dǎo)致數(shù)據(jù)模糊。 對(duì)于這種情況,我們一般可以在寫(xiě)Excel的處理器中增加一些設(shè)置,讓Excel在轉(zhuǎn)換PDF的時(shí)候,可以自適應(yīng)PDF頁(yè),并且對(duì)于一頁(yè)存放不下的數(shù)據(jù),自動(dòng)分配到下一頁(yè)。同時(shí)設(shè)置打印時(shí)每一頁(yè)上都增加標(biāo)題行。
我在這里是使用了easyexcel生成Excel,并且使用了一個(gè)單獨(dú)的處理器,小伙伴們?cè)谑褂玫臅r(shí)候,也可以將打印PDF的設(shè)置項(xiàng)作為一個(gè)單獨(dú)的處理器去使用。該處理器的完整代碼如下:
package com.gyg.util; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; /** * @author YunGang.Guo * @date 2022/04/20 11:30 **/ public class PrintExcelHandler implements SheetWriteHandler { /** * 該sheet頁(yè)的表頭列數(shù),用于凍結(jié)表頭 */ int handColNum; PrintExcelHandler(int handColNum){ this.handColNum = handColNum; } @Override public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { } @Override public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { Sheet sheet = writeSheetHolder.getSheet(); //凍結(jié)表頭,設(shè)置打印的每一頁(yè)上都加上標(biāo)題行 CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, handColNum); sheet.setRepeatingRows(cellRangeAddress); //設(shè)置橫向打印 sheet.getPrintSetup().setLandscape(true); sheet.getPrintSetup().setFitHeight((short) 0); //設(shè)置所有列為一頁(yè) sheet.setFitToPage(true); //設(shè)置是否顯示網(wǎng)格線 sheet.setDisplayGridlines(false); } }
以上就是我在使用easyexcel生成Excel,并且使用jacob轉(zhuǎn)換成PDF時(shí)遇到的兩個(gè)問(wèn)題,暫且做這兩個(gè)記錄,如果小伙伴們還有其他問(wèn)題,可以一起交流!
總結(jié)
到此這篇關(guān)于利用Jacob將Excel轉(zhuǎn)換PDF問(wèn)題的文章就介紹到這了,更多相關(guān)Jacob將Excel轉(zhuǎn)換PDF內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入淺出講解Spring框架中AOP及動(dòng)態(tài)代理的應(yīng)用
在軟件業(yè),AOP為Aspect?Oriented?Programming的縮寫(xiě),意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)2022-03-03集合框架(Collections Framework)詳解及代碼示例
這篇文章主要介紹了集合框架(Collections Framework)詳解及代碼示例,文章涉及集合數(shù)組的區(qū)別,collection接口,iterator迭代器,list接口及其用法,LinkedHashSet集合等有關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11深入聊一聊springboot項(xiàng)目全局異常處理那些事兒
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于springboot項(xiàng)目全局異常處理那些事兒,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01Spring Boot + Mybatis 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源案例分析
這篇文章主要介紹了Spring Boot + Mybatis 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源,需要的朋友可以參考下2018-11-11MyBatis-Plus updateById不更新null值的方法解決
用Mybatis-Plus的updateById()來(lái)更新數(shù)據(jù)時(shí),無(wú)法將字段設(shè)置為null值,更新后數(shù)據(jù)還是原來(lái)的值,本文就來(lái)詳細(xì)的介紹一下解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08