如何将单个文本对象拆分成多个?

什么是PDF中的文本对象?

PDF中的一行文本,通常由一个或多个文本对象组成。一个文本对象可以包含一个或多个字符,所有字符共用同一个字体和文本属性(文本属性包含:字号、颜色、透明度、词间距等),不能换行。下图所示就是用福昕PDF高级编辑器(编辑->编辑对象->文本对象)选中的一个文本对象。

所以在使用SDK编辑PDF中的文本时,除了SDK本身提供的搜索替换、段落编辑等相对高级的接口外,通常是需要直接操作文本对象的。

拆分文本对象的场景:

例如一个文本对象比较长,希望将文本对象中间,将指定区域的几个字符进行删除用色块填充,或者希望只移动文本对象中的部分文本。此时就需要将文本拆分成三段,只处理中间的一段,保证前后两端的剩余文本位置,和文本属性不发生改变。

实现方式

福昕SDK提供对象图形、图片、文本对象克隆的接口,并且对于文本对象,还提供获接口取每个字符的宽高、位置等细节信息,通过这些信息,可以实现文本对象的拆分。

例如用户高亮了这个文本对象的中间部分

拆分后的效果应该是:

实现该效果的java实例代码如下:

    static void SplitTetObject() throws PDFException 
{
        PDFDoc doc=new PDFDoc("D:\\AboutFoxit.pdf");        doc.load(null);        PDFPage page= doc.getPage(0);        page.startParse(0,null,true);        //先在PDF上用一个矩形注释,或者高亮注释框选出要单独拆分出的文本        Annot annot= page.getAnnot(0);        RectF selectRect=annot.getRect();        GraphicsObjectArray objArray= page.getGraphicsObjectsAtRectangle(annot.getRect(), e_TypeText);        //objArraySelected 用于存放被矩形区域框选中的文本对象        GraphicsObjectArray objArraySelected=new GraphicsObjectArray();        int textObjCount=objArray.getSize();        for(int i=0;i<textObjCount;i++)        {            TextObject textObj=objArray.getAt(i).getTextObject();            RectF rect= textObj.getRect();            RectF rectObj= textObj.getRect();             rect.intersect(selectRect);             //如果矩形区域不包含             if(rect.width()<=0)                 continue;             //如果完全包含             if(rect.width()==rectObj.width())                 objArraySelected.add(textObj);             else             {                 String str=textObj.getText();                 int charS=-1;                 int charE=-1;                 for (int charIndex=0;charIndex<str.length();charIndex++)                 {                     PointF charPos =textObj.getCharPos(charIndex);                     float charWidth=textObj.getCharWidthByIndex(charIndex);                     if(charPos.getX()>=selectRect.getLeft()&charS==-1) {                         charS = charIndex;                         charE=charIndex;                         continue;                     }                     else if(charPos.getX()>=selectRect.getRight())                     {                         charE=charIndex;                         break;                     }                 }                 getSelectTextObject(textObj,charS,charE,page,objArraySelected);                 i--;                 textObjCount--;             }        }        page.generateContent();        doc.saveAs("D:\\result.pdf",0);  
  }

  
  static void getSelectTextObject(TextObject textObj,int startCharIndex,int endCharIndex,PDFPage page,GraphicsObjectArray graphicsObjectArray) throws PDFException {
        String str=textObj.getText();
        if(startCharIndex!=0) {
            TextObject t1 = textObj.clone().getTextObject();
            t1.setText(str.substring(0, startCharIndex));
            //插入新克隆的文本
            page.insertGraphicsObject(page.getLastGraphicsObjectPosition(0),t1);
            Matrix2D matrix=t1.getMatrix();
        }
        {
            TextObject t2 = textObj.clone().getTextObject();
            t2.setText(str.substring(startCharIndex, endCharIndex));
            page.insertGraphicsObject(page.getLastGraphicsObjectPosition(0),t2);
            Matrix2D matrix=t2.getMatrix();
            t2.transform(new Matrix2D(1,0,0,1,textObj.getCharPos(startCharIndex).getX()-textObj.getCharPos(0).getX(),0),true);
            //将选中的一段文本对象存放进数组里
            graphicsObjectArray.add(t2);
        }
        if(endCharIndex!=textObj.getCharCount()-1)
        {
            TextObject t3 = textObj.clone().getTextObject();
            t3.setText(str.substring(endCharIndex,textObj.getCharCount()));
            page.insertGraphicsObject(page.getLastGraphicsObjectPosition(0),t3);
            Matrix2D matrix=t3.getMatrix();
            t3.transform(new Matrix2D(1,0,0,1,textObj.getCharPos(endCharIndex).getX()-textObj.getCharPos(0).getX(),0),true);
        }
        //删除原本的文本对象
        page.removeGraphicsObject(textObj);
    }