poi4 生成 PPTX 文字段落前面始终有一个换行符,可以去掉吗

代码是



    org.apache.poi
    poi
    4.1.2


    org.apache.poi
    poi-ooxml
    4.1.2


    commons-io
    commons-io
    2.6

public static void main(String[] args) throws IOException {
    XMLSlideShow ppt = new XMLSlideShow();
    XSLFSlide slide = ppt.createSlide();
    XSLFTextBox shape = slide.createTextBox();
    XSLFTextParagraph p = shape.addNewTextParagraph();
    p.setTextAlign(TextParagraph.TextAlign.CENTER);
    String x2 = "2.96";  //水平位置
    String y2 = "13.91"; //垂直位置
    String w2 = "10.56"; //宽度
    String h2 = "0.50";  //高度
    shape.setAnchor(new Rectangle2D.Double(Double.valueOf(x2) / 3.53 * 100, Double.valueOf(y2) / 3.53 * 100, Double.valueOf(w2) / 3.53 * 100, Double.valueOf(h2) / 3.53 * 100));
    p.clearTabStops();
    p.setTextAlign(TextParagraph.TextAlign.JUSTIFY_LOW);
    XSLFTextRun r1 = p.addNewTextRun();
    r1.setCharacterSpacing(0);
    r1.setText("The");
    r1.setFontColor(Color.blue);
    r1.setFontSize(24.0);
    XSLFTextRun r2 = p.addNewTextRun();
    r2.setText(" quick");
    r2.setFontColor(Color.red);
    r2.setBold(true);
    XSLFTextRun r3 = p.addNewTextRun();
    r3.setText(" brown");
    r3.setFontSize(12.0);
    r3.setItalic(true);
    r3.setStrikethrough(true);
    XSLFTextRun r4 = p.addNewTextRun();
    r4.setText(" fox");
    r4.setUnderlined(true);
    //2.使用 FileOutputStream 类将更改保存到PPT文档:
    String filePath = "D:" + File.separator + "test.pptx";
    //使用了File对象打开文件然后读取
 File file = new File(filePath);
    FileOutputStream out = new FileOutputStream(file);
    //3.保存文件
 ppt.write(out);
    out.close();
    System.out.println(filePath);
}

生成的pptx文字前面有换行符,影响了文字位置
image
试过poi3.9版本生成pptx的文件前面没有换行符
但是poi3.9不支持内嵌字体,需求要做内嵌字体
求大佬带带我

最佳答案

其实我没用过poi,不熟悉语法,只是单纯从解决问题的角度试了一下。最后结果回过头思考哈,很显然,要是题主再稍微细心一点点,没准就可以自己解决这个问题了,思路如下

首先先排除是不是题主自己的代码导致的多余一行。我删除了题主自行添加的一行The,quick等相关代码的最小上一层,从代码逻辑看起来要追溯到shape.addNewTextParagraph(),类似这样
image.png

然后执行,可以发现,最后明显还是有一个段落的。

image.png

那就说明,这个应该不是题主自行的一些操作导致的,因为所有题主额外段落添加操作都删除了,说明这是poi自己初始化的时候就有了这么一个段落对象(XSLFTextParagraph

因为题主添加的段落代码是从shape.addNewTextParagraph(),既然我们怀疑poi自己初始化时候就有一个默认XSLFTextParagraph,那我们从shape.addNewTextParagraph()进入源码观察一下这个XSLFTextParagraph对象最终是存储在shape对象中的哪个属性的,然后再直接debug去看当shape创建出来(也就是slide.createTextBox())的时候,那个属性是否有默认的段落

进入shape.addNewTextParagraph()源码,可以看到XSLFTextParagraph是存在_paragraphs属性的
image.png

接着我们直接debugshape对象刚被创建出来的时候,一目了然,果然这时候_paragraphs中已经有了一个XSLFTextParagraph
image.png

所以解决问题的方式就很简单了,两种模式

  1. 要么不用shape.addNewTextParagraph()去创建一个新XSLFTextParagraph,而是获取默认那个XSLFTextParagraph,然后再p.addNewTextRun(),我直接打了一下shape.getText一看,果然有个shape.getTextParagraphs()方法

image.png

  1. 还有一种就是,既然不想用默认的,按道理讲,poi应该提供了类似清理所有_paragraphs的方法,一般取名大体都是clear比较常见吧,果然,我输入了一个clear就有一个方法clearText()

image.png

当然由于我不太熟悉api,所以我还是进去看了哈源码,看到_paragraphs.clear()我就安心了
image.png

最后,我还是使用了shape.clearText()看看可不可以叭,万一打脸了呢~(其实主要是这个修改起来很简单嘛,哈哈哈),我们在shape.addNewTextParagraph()之前去clear一把
image.png

最后结果,对比了一下3.9的版本,当然自己去里面移动哈光标,确实只有一个段落,看起来是ok的,题主可以自己试试看叭
image.png