繁体   English   中英

resizeToFitText()导致带有非拉丁字符的文本溢出文本框

[英]resizeToFitText() leads to text overflowing textbox with non-Latin characters

我们正在使用Apache POI 3.16(撰写本文时的最新版本)。

我们的代码如下所示:

XSLFTextBox textBox = slide.createTextBox();
XSLFTextParagraph paragraph = textBox.getTextParagraphs().get(0);
XSLFTextRun textRun = paragraph.addNewTextRun();
textRun.setText("non-Latin characters here");
textBox.setAnchor(new Rectangle(left, top, width, 10000));
textBox.resizeToFitText();

请注意,我们不会以任何方式更改字体样式。

此代码导致文本溢出文本框:

文本溢出文本框与Apache POI

它似乎不是Apache POI错误。 我只能找到关于resizeToFitText()两个问题( 错误45140错误47594 ),两者都与换行符相关( 这是我们遇到的另一个问题 )。

关于我们如何规避问题的任何想法?

更新1:这是一个完整的,独立的repro案例:

import java.awt.Rectangle;
import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;

public class TextBoxOverflow {
    public static void main(String[] args) throws Exception {

        XMLSlideShow slideShow = new XMLSlideShow();

        XSLFSlide slide = slideShow.createSlide();

        XSLFTextBox textBox = slide.createTextBox();
        XSLFTextParagraph paragraph = textBox.getTextParagraphs().get(0);
        XSLFTextRun textRun = paragraph.addNewTextRun();
        textRun.setText(
            "ちょっと早いけどTシャツが着たくなる季節♡お母さんの影響か、非常に恐竜が大好きです。もう飼いたいくらい大好きです。#ジュラシックワールド のラプトル4姉妹とか激的に可愛くて可愛くて可愛くて可愛いです。めろめろ、大好き♡お母さんも恐竜が好きで、小さい頃、古代生物の図鑑を一緒に見てたの思い出す〜とい");
        textBox.setAnchor(new Rectangle(50, 50, 200, 5000));
        textBox.resizeToFitText();

        FileOutputStream out = new FileOutputStream("TextBoxOverflow.pptx");
        slideShow.write(out);
        out.close();
        slideShow.close();
    }
}

结果:

文本溢出文本框与Apache POI

更新2:在Apache POI的错误跟踪器中记录错误:
https://bz.apache.org/bugzilla/show_bug.cgi?id=61169

到目前为止,这似乎是Windows不良支持的一个缺点。

如果我运行以下代码

import java.awt.Rectangle;
import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;

import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;

public class TextBoxOverflow {
    public static void main(String[] args) throws Exception {

        XMLSlideShow slideShow = new XMLSlideShow();

        XSLFSlide slide = slideShow.createSlide();

        XSLFTextBox textBox = slide.createTextBox();
        XSLFTextParagraph paragraph = textBox.getTextParagraphs().get(0);
        XSLFTextRun textRun = paragraph.addNewTextRun();

        textRun.setText(
            "ちょっと早いけどTシャツが着たくなる季節♡お母さんの影響か、非常に恐竜が大好きです。もう飼いたいくらい大好きです。#ジュラシックワールド のラプトル4姉妹とか激的に可愛くて可愛くて可愛くて可愛いです。めろめろ、大好き♡お母さんも恐竜が好きで、小さい頃、古代生物の図鑑を一緒に見てたの思い出す〜とい");

        textBox.setAnchor(new Rectangle(50, 50, 200, 5000));

        double heigth = textBox.getTextHeight();
System.out.println(heigth);

        textBox.resizeToFitText();

        CTShape ctshape = (CTShape)textBox.getXmlObject();
System.out.println(ctshape.getSpPr());

        //set TextBox autofit the text 
        ctshape.getTxBody().getBodyPr().addNewSpAutoFit();

        FileOutputStream out = new FileOutputStream("TextBoxOverflow.pptx");
        slideShow.write(out);
        out.close();
        slideShow.close();
    }
}

Linux然后我得到:

在此输入图像描述

正如你所看到的textBox.getTextHeight()330.0cy在锚是cy="4203700"

这会导致适当调整大小的文本框。

如果我在Windows也这样做,那么我得到:

在此输入图像描述

正如你所看到的textBox.getTextHeight()183.78125cy在锚是cy="2346722"

这肯定会导致文本框只有一半的高度。

如果你做ctshape.getTxBody().getBodyPr().addNewSpAutoFit(); 然后设置“自动调整文本框大小到文本”标志。 然后,至少对PowerPoint中的文本进行任何更改都将导致自动调整该框。


2017年6月10日编辑:

找到至少一个近似的解决方案。 如果我们将XSLFTextRun的字体系列设置为“Meiryo”,那么在Windows中,文本框高度的确定也大致正确:

import java.awt.Rectangle;
import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;

import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;

public class TextBoxOverflow {
    public static void main(String[] args) throws Exception {

        XMLSlideShow slideShow = new XMLSlideShow();

        XSLFSlide slide = slideShow.createSlide();

        XSLFTextBox textBox = slide.createTextBox();
        XSLFTextParagraph paragraph = textBox.getTextParagraphs().get(0);
        XSLFTextRun textRun = paragraph.addNewTextRun();

        String fontfamily = "Meiryo";
        textRun.setFontFamily(fontfamily);  

        textRun.setText(
            "ちょっと早いけどTシャツが着たくなる季節♡お母さんの影響か、非常に恐竜が大好きです。もう飼いたいくらい大好きです。#ジュラシックワールド のラプトル4姉妹とか激的に可愛くて可愛くて可愛くて可愛いです。めろめろ、大好き♡お母さんも恐竜が好きで、小さい頃、古代生物の図鑑を一緒に見てたの思い出す〜とい");

        textBox.setAnchor(new Rectangle(50, 50, 200, 5000));

        double heigth = textBox.getTextHeight();
System.out.println(heigth);

        textBox.resizeToFitText();

        CTShape ctshape = (CTShape)textBox.getXmlObject();
System.out.println(ctshape.getSpPr());

        //set TextBox autofit the text 
        ctshape.getTxBody().getBodyPr().addNewSpAutoFit();

        FileOutputStream out = new FileOutputStream("TextBoxOverflow.pptx");
        slideShow.write(out);
        out.close();
        slideShow.close();
    }
}

导致在Linux以与上述相同的值:该textBox.getTextHeight()330.0cy在锚是cy="4203700"

但是,现在在WindowstextBox.getTextHeight()353.8330078125cy在锚是cy="4506379" ctshape.getTxBody().getBodyPr().addNewSpAutoFit(); 我认为这是可以接受的。

不清楚是谁应该为此负责。 无论是Microsoft由于其较差的Unicode支持或Java ,因为其较差的字体管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM