Using Jacob to convert Excel to PDF problem summary

Continue to create, accelerate growth! This is the first day of my participation in the "Nuggets Daily New Plan · June Update Challenge", click to view the details of the event

Hello, everyone, I'm a little gray ape, a programmer who is very good at writing bugs!

Long time no see, sharing a new problem recently encountered in project development, about the need to use easyexcel to generate Excel, and use jacob to convert to PDF, I found some related tutorials on the Internet at first, and after screening, I found that it was still Using jacob to call office software for conversion is the most reliable. Then I will share with you a tutorial on using jacob to convert Excel files to PDF, a summary of two methods for converting Excel to PDF

But later I found in practice that the original code can only achieve basic conversion, and some problems will arise for some more complex or large data code.

The basic operation of converting with Jacob is similar to other tutorials on the Internet. Here I mainly record some of the problems I encountered in the conversion, as well as some things added on the basis of the most basic Excel-to-PDF code.

Problem 1. When there are many Excel data columns, the columns in the PDF are not fully printed.

For some more complex data tables, there are many data columns. Sometimes when converting PDF according to the normal settings, the column display is often incomplete and some columns overflow. In response to this problem, you can do some settings in Excel to convert PDF. The setting items and their parameters can be set in the following code:

Dispatch.put(value, "key",);
复制代码

Here I set properties such as scaling, vertical printing, row and column to solve the above problems. These settings can be seen in the code below. You can directly do the same settings in the corresponding position of your conversion code. Of course, the code below is directly configured and can be copied and used directly.

Conversion function:

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实现excel转PDF
     *
     * @param inputFilePath  导入Excel文件路径
     * @param outputFilePath 导出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的集合对象
            Dispatch sheets = Dispatch.get(excel, "sheets").toDispatch();
            //获取到总表数
            int count = Dispatch.get(sheets, "count").changeType(Variant.VariantInt).getInt();
            for (int i = 1; i <= count; i++) {
                //获取到sheet页
                Dispatch sheet = Dispatch.invoke(sheets, "Item", Dispatch.Get, new Object[]{i}, new int[1]).toDispatch();
                Dispatch page = Dispatch.get(sheet, "PageSetup").toDispatch();
                //是否设置区域打印
                Dispatch.put(page, "PrintArea", false);
                //设置横向打印还是纵向打印
                Dispatch.put(page, "Orientation", 2);
                //设置缩放,值为100或false
                Dispatch.put(page, "Zoom", false);
                //所有行为一页
                Dispatch.put(page, "FitToPagesTall", false);
                //所有列为一页(1或false)
                Dispatch.put(page, "FitToPagesWide", 1);
                log.info("sheet页[" + i + "]设置成功,");
            }

            //转换格式
            Object[] obj2 = {
                    //PDF格式等于0
                    new Variant(0),
                    outputFilePath,
                    //0=标准(生成的PDF图片不会模糊),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();
        }
    }
}

复制代码

Problem 2. When there is a large amount of data, the PDF page is blurred and solved

In ordinary projects, the amount of data in the Excel table that needs to be exported is very large. In this case, it is generally impossible for one table to correspond to one page in the converted PDF. However, when Jacob converts, the default is to make a table on one page, which causes the data to be scaled to a particularly small size, resulting in blurred data. In this case, we can generally add some settings in the processor that writes Excel, so that when Excel converts PDF, it can adapt to PDF pages, and automatically assign data that cannot be stored on one page to the next page. At the same time, it is set to add a header row to each page when printing.

Here I use easyexcel to generate Excel, and use a separate processor. When you use it, you can also use the settings for printing PDF as a separate processor. The complete code for this processor is as follows:

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页的表头列数,用于冻结表头
     */
    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();
        //冻结表头,设置打印的每一页上都加上标题行
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, handColNum);
        sheet.setRepeatingRows(cellRangeAddress);
        //设置横向打印
        sheet.getPrintSetup().setLandscape(true);
        sheet.getPrintSetup().setFitHeight((short) 0);
        //设置所有列为一页
        sheet.setFitToPage(true);
        //设置是否显示网格线
        sheet.setDisplayGridlines(false);
    }
}

复制代码

The above are the two problems I encountered when using easyexcel to generate Excel and using jacob to convert to PDF. I will make these two records for the time being. If you have other questions, you can communicate together!

I'm Gray Ape, see you next time!

おすすめ

転載: juejin.im/post/7103033813319548958