当前位置: 首页 > 工具软件 > XSSF > 使用案例 >

java使用XSSF设置页眉页脚及打印样式

年光明
2023-12-01

需求背景

有报表,就抛不开打印的需求。原本打印功能都是由前端实现,包括了打印标题、页眉页脚、标题行等功能。随着需求越来越多,前端不干了,跟领导反馈实现了一个功能,引发了若干bug(会哭的孩子有奶喝)。所以,不哭的孩子(我这个后端)只能接下了这个后端打印的需求了。该篇文章适合中级以上开发阅读。

开发前需要引入poi包

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

事先声明:

推荐使用XSSF而不是HSSF,因为前者比后者更有优势。具体区别如下:

  1. 文件格式

HSSF:是操作Excel97-2003版本,扩展名为.xls。

XSSF:是操作Excel2007版本开始,扩展名为.xlsx。

还有一个更高版本的SXSSF:是在XSSF基础上,POI3.8版本开始提供的一种支持低内存占用的操作方式,扩展名为.xlsx。

  1. 兼容性

Excel2007版本可以打开.xls文件,反之则不能。

  1. 支持的行列数

.xls支持一个sheet最大行数65536,最大列数256。

.xlsx支持一个sheet最大行数1048576,最大列数16384。

而且.xlsx文件比.xls的压缩率高

具体实现

1.实现代码

    /**
     * 设置页眉页脚
     * 
     * @author: xxx
     * @date: 2023-02-02 09:43:20
     * @param xssfSheet 需要设置的sheet页对象
     * @param jsonObject 页眉页脚及打印相关配置
     * @param queryParam 查询参数:与业务相关,用于获取值,可忽略
     */
    private void setHeaderAndFooter(XSSFSheet xssfSheet, JSONObject jsonObject, JSONObject queryParam) {
        // 打印设置start
        XSSFPrintSetup ps = xssfSheet.getPrintSetup();
        // 页眉页脚边距
        ps.setHeaderMargin(0.1);
        ps.setFooterMargin(0.1);
        // 设置默认A4纸张
        ps.setPaperSize(XSSFPrintSetup.A4_PAPERSIZE);
        // 横向打印
        ps.setLandscape(true);
        // 将所有列打印在一页
        ps.setFitHeight((short)0);
        xssfSheet.setFitToPage(true);
        // 水平居中
        xssfSheet.setHorizontallyCenter(true);
        // 设置标题行
        int headerStartNum = jsonObject.getInteger("headerStartNum"); // 开始行号
        if(0 < headerStartNum) {
            int headerEndNum = jsonObject.getInteger("headerEndNum"); // 结束行号
            // 下标从0开始
            CellRangeAddress rowRangeRef = new CellRangeAddress(headerStartNum - 1, headerEndNum - 1, -1, -1);
            xssfSheet.setRepeatingRows(rowRangeRef);
        }
        // 打印设置end

        // 页眉页脚start
        JSONObject headerAndFooter = jsonObject.getJSONObject("headerAndFooter");
        if (headerAndFooter.size() < 1) {
            return;
        }
        // 定义页眉左中右对象
        StringBuffer headerLeft = new StringBuffer(""), headerCenter = new StringBuffer(""), headerRight = new StringBuffer("");
        
        if (null != headerAndFooter) {
            // 标题内容
            String titleValue = headerAndFooter.getJSONObject("printTitleObj").getString("value");
            // 如果有标题,则设置页眉的第一行
            if (StringUtils.isNotEmpty(titleValue)) {
                headerLeft.append("&B&18 \n&B&9 \n");
                headerCenter.append("&B&18" + titleValue + "\n&B&9 \n");
                headerRight.append("&B&18 \n&B&9第 &P 页,共 &N 页 \n");
            }

            // 处理页眉样式
            JSONArray printerHeaderList = headerAndFooter.getJSONArray("printerHeaderList");
            if (printerHeaderList.size() > 0) {
                Header header = xssfSheet.getHeader();
                for (int i = 0; i < printerHeaderList.size(); i++) {
                    JSONObject iJSONObject = printerHeaderList.getJSONObject(i);
                    JSONArray list = iJSONObject.getJSONArray("list");
                    for (int j = 0; j < list.size(); j++) {
                        // 获取内容
                        // 全部为业务系统自定义内容,为的是获取页眉需要设置的值,可忽略
                        JSONObject jList = list.getJSONObject(j);
                        String typeValue = jList.getString("typeValue");
                        String labelValue = jList.getString("labelValue");
                        String dsValue = jList.getString("doubleSelectValue");
                        String inputValue = jList.getString("inputValue");
                        String selectValue = jList.getString("selectValue");
                        labelValue = StringUtils.isEmpty(labelValue) ? "" : labelValue + ":";
                        String value = "";
                        if ("input".equals(typeValue) && StringUtils.isNotEmpty(inputValue)) {
                            value = queryParam.getString(inputValue);
                        }
                        if ("select".equals(typeValue) && StringUtils.isNotEmpty(selectValue)) {
                            if (selectValue.indexOf("userInfo__") > -1) {
                                String fieldName = selectValue.split("__")[1];
                                String getFieldName = "get" + fieldName.replaceFirst(fieldName.substring(0, 1),
                                    fieldName.substring(0, 1).toUpperCase());
                                try {
                                    value = UserInfoHolder.getCurrentUserInfo().getClass().getMethod(getFieldName)
                                        .invoke(UserInfoHolder.getCurrentUserInfo()).toString();
                                } catch (Exception e) {
                                    log.error("获取用户信息异常:" + e.toString());
                                }
                            } else if ("other-time-all".equals(selectValue)) {
                                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                value = LocalDateTime.now().format(dtf);
                            } else {
                                value = queryParam.getString(selectValue + "__showContent");
                            }
                        }
                        if ("doubleSelect".equals(typeValue) && StringUtils.isNotEmpty(dsValue)) {
                            String ldsValue = jList.getString("labelDoubleSelectValue");
                            value = queryParam.getString(selectValue) + ldsValue + queryParam.getString(dsValue);
                        }
                        value = "&9" + labelValue + value;
                        if (i > 0) {
                            value += "\n";
                        }
                        // 判断位置并赋值
                        if (0 == j) {
                            headerLeft.append(value);
                        } else if (1 == j) {
                            headerCenter.append(value);
                        } else {
                            headerRight.append(value);
                        }
                    }

                }
                // 赋值页眉内容
                header.setLeft(headerLeft.toString());
                header.setCenter(headerCenter.toString());
                header.setRight(headerRight.toString());
            }

            // 处理页脚样式
            JSONArray printerFooterList = headerAndFooter.getJSONArray("printerFooterList");
            if (printerFooterList.size() > 0) {
                StringBuffer footLeft = new StringBuffer(""), footCenter = new StringBuffer(""), footRight = new StringBuffer("");
                Footer footer = xssfSheet.getFooter();
                for (int i = 0; i < printerFooterList.size(); i++) {
                    // 具体实现同页眉
                }
                footer.setLeft(footLeft.toString());
                footer.setCenter(footCenter.toString());
                footer.setRight(footRight.toString());
            }
        }
    }

2.业务属性说明

headerAndFooter:页眉页脚设置的json配置对象;

printTitleObj:标题内容;

printerHeaderList:页眉对象集合,具体不做赘述;

printerFooterList:页脚对象集合。

3.页眉页脚样式说明

&B:加粗;

&18:18号字体;

&P:当前页码数;

&N:总页数。

 类似资料: