利用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)上其他的教程基本類(lèi)似,在這里我主要記錄一下我在轉(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)文章
SpringBoot2.6.x默認(rèn)禁用循環(huán)依賴(lài)后的問(wèn)題解決
由于SpringBoot從底層逐漸引導(dǎo)開(kāi)發(fā)者書(shū)寫(xiě)規(guī)范的代碼,同時(shí)也是個(gè)憂(yōu)傷的消息,循環(huán)依賴(lài)的應(yīng)用場(chǎng)景實(shí)在是太廣泛了,所以SpringBoot 2.6.x不推薦使用循環(huán)依賴(lài),本文給大家說(shuō)下SpringBoot2.6.x默認(rèn)禁用循環(huán)依賴(lài)后的應(yīng)對(duì)策略,感興趣的朋友一起看看吧2022-02-02
推薦兩款java開(kāi)發(fā)實(shí)用工具 hutool 和 lombok
通過(guò)本文給大家推薦兩款java開(kāi)發(fā)實(shí)用工具 hutool 和 lombok,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-04-04
SpringBoot實(shí)現(xiàn)application配置信息加密
在配置文件中,我們有開(kāi)發(fā)環(huán)境配置和生產(chǎn)環(huán)境配置,而生產(chǎn)環(huán)境的配置信息是需要做好防護(hù)的,避免外泄,所以本文為大家整理了application配置信息加密的方法,需要的可以參考下2023-07-07
springboot中實(shí)現(xiàn)通過(guò)后臺(tái)創(chuàng)建臨時(shí)表
這篇文章主要介紹了springboot中實(shí)現(xiàn)通過(guò)后臺(tái)創(chuàng)建臨時(shí)表操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
springboot2.3之后hibernate-validator依賴(lài)缺失【踩坑】
這篇文章主要介紹了springboot2.3之后hibernate-validator依賴(lài)缺失【踩坑】,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Java之a(chǎn)pi網(wǎng)關(guān)斷言及過(guò)濾器案例講解
這篇文章主要介紹了Java之a(chǎn)pi網(wǎng)關(guān)斷言及過(guò)濾器案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
解決springcloud啟動(dòng)時(shí)報(bào)錯(cuò)Connection refused:connect問(wèn)題
這篇文章主要介紹了解決springcloud啟動(dòng)時(shí)報(bào)錯(cuò)Connection refused:connect問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

