SpringBoot项目借助POI(3.16)实现docx文件加入页码(奇偶页页码格式有区别)

前言

docx的相关知识:
docx文件的xml解析

需求描述:

需要给一个word(docx格式)文件加上页码,奇数页页码在右下角,偶数页页码在左下角,并且页码的格式为“- num -”。
如:“- 1 -”、“- 2 -”
奇数页
在这里插入图片描述
偶数页
在这里插入图片描述

后端开发框架

SpringBoot

maven引用第三方库

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.16</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.16</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>3.16</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.10-FINAL</version>
</dependency>

实现逻辑

  1. 读入docx文件,
  2. 增加奇偶页标识(一些文件的设置,具体的流程我也不懂,详情见下面的代码)
  3. 设置全部页的页码都在右下角,按照对应格式设置页码
  4. 设置偶数页的页码都在左下角,按照对应格式设置页码

具体代码(包含注释)


/**
  * 在docx文件中加入奇偶页码(奇数页面加入的页码靠右,偶数页面加入的页码靠左)
  * 页码样式如下(注意"-"和数字之间均有一个空格,“”中间的为页码样式)
  *“- 1 -”
  *“- 2 -”
  * @param docxFilePath  需要加入页码docx文件的路径
  * @return 无返回值,在原文件上直接修改
  *
  */
public void addOddAndEvenPageNumber(String docxFilePath){
     XWPFDocument document = null;
     try {
         InputStream is = new ByteArrayInputStream(FileUtil.getContent(docxFilePath));
         //获取docx对象  增加 奇偶页
         document = new XWPFDocument(is);
         //添加奇偶页标识
         addNewEvenAndOddHeaders(document);
         //为全部页面创建靠右的页码
         createFooter(document, HeaderFooterType.DEFAULT, ParagraphAlignment.RIGHT);
         //为偶数页创建靠左的页码
         createFooter(document,HeaderFooterType.EVEN,ParagraphAlignment.LEFT);
         //在指定路径生成对应的文件
         document.write(new FileOutputStream(docxFilePath));
     } catch (IOException e) {
         e.printStackTrace();
     } catch (IllegalAccessException e) {
         e.printStackTrace();
     } catch (NoSuchFieldException e) {
         e.printStackTrace();
     }
 }

/**
 * 创建页码
 *
 * @param document  需要引用的XWPFDocument对象
 * @param headerFooterType  页码的样式  HeaderFooterType.DEFAULT  所有页面   HeaderFooterType.EVEN 偶数下标页面
 * @param paragraphAlignment  脚标靠哪个方向  如:ParagraphAlignment.RIGHT  靠右
 * @throws IOException
 * @throws NoSuchFieldException
 * @throws IllegalAccessException
 */
static void createFooter(XWPFDocument document, HeaderFooterType headerFooterType, ParagraphAlignment paragraphAlignment) throws IOException, NoSuchFieldException, IllegalAccessException {
    //设置XWPFFooter类型脚标对象
    XWPFFooter footer = document.createFooter(headerFooterType);//创建一个新的XWPFFooter对象
    XWPFParagraph paragraph = footer.createParagraph();//创建新的XWPFParagraph对象
    paragraph.setAlignment(paragraphAlignment);//设置样式靠右
    //设置段落对象
    XWPFRun runPre = paragraph.createRun();//新的段落对象
    runPre.setText("- ");
    setXWPFRunStyle(runPre,"宋体",14);
    XWPFRun run = paragraph.createRun();//新的段落对象
    CTFldChar fldChar = run.getCTR().addNewFldChar();//新的CTFldChar对象
    fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));
    CTText ctText = run.getCTR().addNewInstrText();
    ctText.setStringValue("PAGE  \\* MERGEFORMAT");
    ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
    setXWPFRunStyle(run,"宋体",14);
    fldChar = run.getCTR().addNewFldChar();
    fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
    //设置段落对象
    XWPFRun runSuf = paragraph.createRun();//新的段落对象
    runSuf.setText(" -");
    setXWPFRunStyle(runSuf,"宋体",14);
}

/**
 * 添加奇偶页标识
 * @param document word对应的XWPFDocument对象
 */
static void addNewEvenAndOddHeaders(XWPFDocument document){
    //设置奇偶页辨别
    try{
        Field _settings = XWPFDocument.class.getDeclaredField("settings");
        _settings.setAccessible(true);
        XWPFSettings xwpfsettings = (XWPFSettings)_settings.get(document);
        Field _ctSettings = XWPFSettings.class.getDeclaredField("ctSettings");
        _ctSettings.setAccessible(true);
        CTSettings ctsettings =
                (CTSettings)_ctSettings.get(xwpfsettings);
        ctsettings.addNewEvenAndOddHeaders();
    }catch (Exception e){
        e.printStackTrace();
    }
}

/**
 * 设置页脚的字体样式
 * @param r1 段落元素
 * @param font 段落元素
 * @param fontSize 的大小
 */
static void setXWPFRunStyle(XWPFRun r1, String font, int fontSize) {
    r1.setFontSize(fontSize);
    CTRPr rpr = r1.getCTR().isSetRPr() ? r1.getCTR().getRPr() : r1.getCTR().addNewRPr();
    CTFonts fonts = rpr.isSetRFonts() ? rpr.getRFonts() : rpr.addNewRFonts();
    fonts.setAscii(font);
    fonts.setEastAsia(font);
    fonts.setHAnsi(font);
}

相关链接

How to generate different headers in first page and other pages in poi word XWPF?

XWPFDocument的官方文档传送门

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值