itext5中首行出现标点符号和页脚页码显示的解决方案

做项目中需要动态的生成pdf文档,使用的是java代码生成的方法,在这过程中,发现了标点符号出现在首行的问题,和页码没有显示的问题,我把这两个问题放在同一个类里面解决了。

一、标点符号出现在首行的问题

1. 第一步写一个该类实现SplitCharacter

import com.itextpdf.awt.AsianFontMapper;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.IOException;

/**
 * 该方法仅对中文的标点符号有效 
 *  继承 extends PdfPageEventHelper是为了解决页码显示的问题
 *  implements SplitCharacter 实现该方法时为了解决中文标点符号出现在首行的问题
 */
public class ChineseSplitUtils extends PdfPageEventHelper implements SplitCharacter {

    // line of text cannot start or end with this character
    static final char u2060 = '\u2060';   //       - ZERO WIDTH NO BREAK SPACE

    // a line of text cannot start with any following characters in NOT_BEGIN_CHARACTERS[]
    static final char u30fb = '\u30fb';   //  ・   - KATAKANA MIDDLE DOT
    static final char u2022 = '\u2022';   //  •    - BLACK SMALL CIRCLE (BULLET)
    static final char uff65 = '\uff65';   //  ・    - HALFWIDTH KATAKANA MIDDLE DOT
    static final char u300d = '\u300d';   //  」   - RIGHT CORNER BRACKET
    static final char uff09 = '\uff09';   //  )   - FULLWIDTH RIGHT PARENTHESIS
    static final char u0021 = '\u0021';   //  !    - EXCLAMATION MARK
    static final char u0025 = '\u0025';   //  %    - PERCENT SIGN
    static final char u0029 = '\u0029';   //  )    - RIGHT PARENTHESIS
    static final char u002c = '\u002c';   //  ,    - COMMA
    static final char u002e = '\u002e';   //  .    - FULL STOP
    static final char u003f = '\u003f';   //  ?    - QUESTION MARK
    static final char u005d = '\u005d';   //  ]    - RIGHT SQUARE BRACKET
    static final char u007d = '\u007d';   //  }    - RIGHT CURLY BRACKET
    static final char uff61 = '\uff61';   //  。    - HALFWIDTH IDEOGRAPHIC FULL STOP

    static final char uff70 = '\uff70';   //  ー    - HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
    static final char uff9e = '\uff9e';   //  ゙    - HALFWIDTH KATAKANA VOICED SOUND MARK
    static final char uff9f = '\uff9f';   //  ゚    - HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
    static final char u3001 = '\u3001';   //  、    - IDEOGRAPHIC COMMA
    static final char u3002 = '\u3002';   //  。    - IDEOGRAPHIC FULL STOP
    static final char uff0c = '\uff0c';   //  ,    - FULLWIDTH COMMA
    static final char uff0e = '\uff0e';   //  .    - FULLWIDTH FULL STOP
    static final char uff1a = '\uff1a';   //  :    - FULLWIDTH COLON
    static final char uff1b = '\uff1b';   //  ;    - FULLWIDTH SEMICOLON
    static final char uff1f = '\uff1f';   //  ?    - FULLWIDTH QUESTION MARK
    static final char uff01 = '\uff01';   //  !    - FULLWIDTH EXCLAMATION MARK
    static final char u309b = '\u309b';   //  ゛    - KATAKANA-HIRAGANA VOICED SOUND MARK
    static final char u309c = '\u309c';   //  ゜    - KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
    static final char u30fd = '\u30fd';   //  ヽ    - KATAKANA ITERATION MARK

    static final char u2019 = '\u2019';   //  ’    - RIGHT SINGLE QUOTATION MARK
    static final char u201d = '\u201d';   //  ”    - RIGHT DOUBLE QUOTATION MARK
    static final char u3015 = '\u3015';   //  〕    - RIGHT TORTOISE SHELL BRACKET
    static final char uff3d = '\uff3d';   //  ]    - FULLWIDTH RIGHT SQUARE BRACKET
    static final char uff5d = '\uff5d';   //  }    - FULLWIDTH RIGHT CURLY BRACKET
    static final char u3009 = '\u3009';   //  〉    - RIGHT ANGLE BRACKET
    static final char u300b = '\u300b';   //  》    - RIGHT DOUBLE ANGLE BRACKET
    static final char u300f = '\u300f';   //  』    - RIGHT WHITE CORNER BRACKET
    static final char u3011 = '\u3011';   //  】    - RIGHT BLACK LENTICULAR BRACKET
    static final char u00b0 = '\u00b0';   //  °    - DEGREE SIGN
    static final char u2032 = '\u2032';   //  ′    - PRIME
    static final char u2033 = '\u2033';   //  ″    - DOUBLE PRIME


    static final char[] NOT_BEGIN_CHARACTERS = new char[]{u30fb, u2022, uff65, u300d, uff09, u0021, u0025, u0029, u002c,
            u002e, u003f, u005d, u007d, uff61,
            uff70, uff9e, uff9f, u3001, u3002, uff0c, uff0e, uff1a, uff1b, uff1f, uff01, u309b, u309c, u30fd,
            u2019, u201d, u3015, uff3d, uff5d, u3009, u300b, u300f, u3011, u00b0,
            u2032, u2033, u2060};

    // a line of text cannot end with any following characters in NOT_ENDING_CHARACTERS[]
    static final char u0024 = '\u0024';   //  $   - DOLLAR SIGN
    static final char u0028 = '\u0028';   //  (   - LEFT PARENTHESIS
    static final char u005b = '\u005b';   //  [   - LEFT SQUARE BRACKET
    static final char u007b = '\u007b';   //  {   - LEFT CURLY BRACKET
    static final char u00a3 = '\u00a3';   //  £   - POUND SIGN
    static final char u00a5 = '\u00a5';   //  ¥   - YEN SIGN
    static final char u201c = '\u201c';   //  “   - LEFT DOUBLE QUOTATION MARK
    static final char u2018 = '\u2018';   //   ‘  - LEFT SINGLE QUOTATION MARK
    static final char u300a = '\u300a';   //  《  - LEFT DOUBLE ANGLE BRACKET
    static final char u3008 = '\u3008';   //  〈  - LEFT ANGLE BRACKET
    static final char u300c = '\u300c';   //  「  - LEFT CORNER BRACKET
    static final char u300e = '\u300e';   //  『  - LEFT WHITE CORNER BRACKET
    static final char u3010 = '\u3010';   //  【  - LEFT BLACK LENTICULAR BRACKET
    static final char u3014 = '\u3014';   //  〔  - LEFT TORTOISE SHELL BRACKET
    static final char uff62 = '\uff62';   //  「   - HALFWIDTH LEFT CORNER BRACKET
    static final char uff08 = '\uff08';   //  (  - FULLWIDTH LEFT PARENTHESIS
    static final char uff3b = '\uff3b';   //  [  - FULLWIDTH LEFT SQUARE BRACKET
    static final char uff5b = '\uff5b';   //  {  - FULLWIDTH LEFT CURLY BRACKET
    static final char uffe5 = '\uffe5';   //  ¥  - FULLWIDTH YEN SIGN
    static final char uff04 = '\uff04';   //  $  - FULLWIDTH DOLLAR SIGN

    static final char[] NOT_ENDING_CHARACTERS = new char[]{u0024, u0028, u005b, u007b, u00a3, u00a5, u201c, u2018, u3008,
            u300a, u300c, u300e, u3010, u3014, uff62, uff08, uff3b, uff5b, uffe5, uff04, u2060};

    private static final SplitCharacter defaultSplitCharacter = new DefaultSplitCharacter();


    public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {

        // Note: If you don't add an try/catch and there is an issue with isSplitCharacter(), iText silently fails and
        // you have no idea there was a problem.
        try {

            char charCurrent = getCharacter(current, cc, ck);

            int next = current + 1;
            if (next < cc.length) {
                char charNext = getCharacter(next, cc, ck);
                for (char not_begin_character : NOT_BEGIN_CHARACTERS) {
                    if (charNext == not_begin_character) {
                        return false;
                    }
                }
            }

            for (char not_ending_character : NOT_ENDING_CHARACTERS) {
                if (charCurrent == not_ending_character) {
                    return false;
                }
            }

            boolean isBasicLatin = Character.UnicodeBlock.of(charCurrent) == Character.UnicodeBlock.BASIC_LATIN;
            if (isBasicLatin)
                return  defaultSplitCharacter.isSplitCharacter(start, current, end, cc, ck);

            return true;

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return true;
    }

    protected char getCharacter(int position, char[] cc, PdfChunk[] ck) {
        if (ck == null || ck[Math.min(position, ck.length - 1)] == null) {
            return cc[position];
        }
        return (char) ck[Math.min(position, ck.length - 1)].getUnicodeEquivalent(cc[position]);
    }
    
}

2、第二步

因为只有Chunk类型中的方法才适用,适用的方法是

 			ChineseSplitUtils chineseSplitUtils = new ChineseSplitUtils();  
 			Paragraph paragraph = new Paragraph("",fontChina18);
            Chunk chunk1  = new Chunk("测试标点符号中文出现在首行啊啊啊啊啊啊啊啊啊,啊",fontChina18);
            chunk1.setSplitCharacter(chineseSplitUtils);
            paragraph.add(chunk1);

二、页码显示的问题

1. 在该类中重写onEndPage的方法

/**
     * 页码显示的设置,只是Document写完一个页面会调用的方法
     */
    @Override
    public void onEndPage(PdfWriter writer, Document doc) {
        BaseFont bfChinese = null;
        try {
            bfChinese = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Font fontChina18 = new Font(bfChinese, 18);
        //添加标题文本
        StringBuffer underline = new StringBuffer();
        for(int i = 0;i<116;i++) {
            underline.append("_");
        }
        Phrase pageNumberPh = new Phrase(String.valueOf(doc.getPageNumber()),fontChina18);
        float center = doc.getPageSize().getRight()/2;//页面的水平中点
        float top = doc.getPageSize().getTop()-36;
        float bottom = doc.getPageSize().getBottom()+36;

        /** 参数xy是指文本显示的页面上的哪个店。alignment指文本在坐标点的对齐方式 */
        ColumnText.showTextAligned(writer.getDirectContent(),Element.ALIGN_CENTER,pageNumberPh,center,bottom,0); //页码
    }

重写了改方法之后会显示页码了,显示的只是当前的页码,没有总页码的显示。

2、在写模板的方法中使用

			PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
            ChineseSplitUtils pdfHeaderFooter = new ChineseSplitUtils();
            writer.setPageEvent(pdfHeaderFooter);

这样就有页码生成了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值