近期项目中在引入ITEXTPDF工具类在线生成PDF文档时遇到文本自动换行时中文标点出现在行首问题因不符合文档要求所以要规避掉行首出现标点符号。多方搜索发现网络中的处置方法大致分为三种种但测试后发现均没有解决项目中现存问题。主要处置方法为:
-
在引用的HTML模板中使用CSS3的样式类如:text-align:justify;text-justify:inter-word;使得文本两端对齐。或在生成文档时调用document类中的方式设置textAlignment属性:TextAlignment.JUSTIFIED两端对齐,属性生效后与未修改时生成的PDF有一定区别但并未解决行首标点问题。
-
修改JAR包源码,在MAVEN库当中找到当前JAR包反编译打开当前JAR包后找到DefaultSplitCharacter类对当前class文件进行修改添加中文标点用来判断当前文本是否允许拆分。但当前类中相互引用位置较多需要统一修改加之在项目中引用其中中文标点UNICODE编码与判断逻辑后文档并无明显效果。
-
创建新PDF文件设置文本对齐方式。将老版本的文档内容拷贝进新文件中。但在拷贝过程中获取到的文档内容只能转换为IMAGE对象或调用copyToPage方法。文本内容又无法携带原油字体或格式故不符合当前问题处置需求。
苦求无果后还是决心自己解决所以在文档文档处置过程中查看DOCUMENT类源码发现其中有一个setSplitCharacters方法可以设置分节规则的方法
public T setSplitCharacters(ISplitCharacters splitCharacters) {
this.setProperty(62, splitCharacters);
return (IPropertyContainer)this;
}
我们看到其中ISplitCharacters 是一个接口类则我们新建一个类实现接口中的方法主动设置分节规则。具体规则如下在分节过程中我们编写正则匹配中文标点判断当前字符前一个或后一个字符是否为中文标点若是则不允许分节否则返回允许。
package com.hag.ydx.common.util;
import com.itextpdf.io.font.otf.Glyph;
import com.itextpdf.io.font.otf.GlyphLine;
import com.itextpdf.layout.splitting.ISplitCharacters;
import com.itextpdf.text.Chunk;
import java.util.Arrays;
/**
* @author zhangwei
* @create 2024--01--11
* 文本内容智能换行解决标点符号在行首问题
*/
public class SplitCharacters implements ISplitCharacters {
/**
* @param glyphLine 文本内容
* @param glyphPos 索引
* */
@Override
public boolean isSplitCharacter(GlyphLine glyphLine, int glyphPos) {
if (glyphLine.size()>2){
if (glyphPos+1<glyphLine.size() && glyphPos!=0){
char[] charLeft = glyphLine.get(glyphPos-1).getChars();
char[] charRight = glyphLine.get(glyphPos+1).getChars();
if (String.valueOf(charRight[0]).matches("[\\p{P}]+") || String.valueOf(charLeft[0]).matches("[\\p{P}]+")){
return false;
}
}
}
return true;
}
}
//写好实现类以后我们只需在生成文档的开始引入即可
Document document = new Document(pdfDocument, PageSize.A4);
document.setSplitCharacters(new SplitCharacters());
此时重新生成文档发现行首标点问题已经处置完成。
备注:在生成文档时行首标点问题解决后可能会出现文本没有对齐或尾行字符间距过大的问题。此时我们需要在文档的HTML模板中去除CSS对文本对齐方式的控制并且在JAVA代码中对Div div = new Div();类设置div.setTextAlignment(TextAlignment.JUSTIFIED);为两端对齐不要使用JUSTIFIED_ALL属性此属性会导致全文扫描对齐,导致文档内容间距变大。