是否可以附加 2 个富文本字符串?

Posted

技术标签:

【中文标题】是否可以附加 2 个富文本字符串?【英文标题】:Is it possible to append 2 rich text strings? 【发布时间】:2012-03-14 09:30:46 【问题描述】:

我需要使用 Apache POI 附加到 Java 中的 2 个 HSSFRichTextStrings。我该怎么做? 我正在做的是我正在获取单元格中已经存在的富文本字符串,并且我正在尝试向其附加一个额外的富文本字符串并将其写回单元格。 请告诉我该怎么做。

【问题讨论】:

查看 javadoc 似乎是不可能的。您始终可以使用连接的字符串创建一个新的 HSSFRichTextStrings 并重新应用格式... 但我不能肯定地说,格式已应用于单元格中已经存在的富文本字符串。那怎么办呢?是否可以获取富文本字符串的字体? 我不知道 HSSFRichTextStrings 是如何工作的,我只是看了一下 javadoc。它具有逐个字符读取和写入格式的方法-所以我原以为您可以使用它们...(poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/…)和(poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/…) 【参考方案1】:

可以附加两个HSSFRichTextStrings,但您必须自己完成大部分工作。您将需要利用HSSFRichTextString 中的以下方法:

numFormattingRuns() - 返回HSFFRichTextString 中的格式化运行次数。 getFontOfFormattingRun(int) - 返回出现在字符串中指定位置的short 字体索引 applyFont(int, int, short) - 在给定的开始索引(包括)和结束索引(不包括)之间应用由short 字体索引引用的字体。

首先,创建一个小类来存储格式化运行统计信息:

public class FormattingRun 
    private int beginIdx;
    private int length;
    private short fontIdx;
    public FormattingRun(int beginIdx, int length, short fontIdx) 
        this.beginIdx = beginIdx;
        this.length = length;
        this.fontIdx = fontIdx;
    
    public int getBegin()  return beginIdx; 
    public int getLength()  return length; 
    public short getFontIndex  return fontIdx; 

接下来,收集两个字符串中每一个的所有格式化运行统计信息。您必须自己遍历字符串以确定每次格式化运行的持续时间。

List<FormattingRun> formattingRuns = new ArrayList<FormattingRun>();
int numFormattingRuns = richTextString.numFormattingRuns();
for (int fmtIdx = 0; fmtIdx < numFormattingRuns; fmtIdx)

    int begin = richTextString.getIndexOfFormattingRun(fmtIdx);
    short fontIndex = richTextString.getFontOfFormattingRun(fmtIdx);

    // Walk the string to determine the length of the formatting run.
    int length = 0;
    for (int j = begin; j < richTextString.length(); j++)
    
        short currFontIndex = richTextString.getFontAtIndex(j);
        if (currFontIndex == fontIndex)
            length++;
        else
            break;
    
    formattingRuns.add(new FormattingRun(begin, length, fontIndex));

接下来,自己连接两个String 值并创建结果HSSFRichTextString

HSSFRichTextString result = new HSSFRichTextString(
     richTextString1.getString() + richTextString2.getString());

最后,应用两组格式化运行,第二组运行偏移第一个字符串的长度。

for (FormattingRun run1 : formattingRuns1)

    int begin = run1.getBegin();
    int end = begin + run1.getLength();
    short fontIdx = run1.getFontIndex();
    result.applyFont(begin, end, fontIdx);

for (FormattingRun run2 : formattingRuns2)

    // offset by string length 1
    int begin = run2.getBegin() + richTextString1.length();
    int end = begin + run2.getLength();
    short fontIdx = run2.getFontIndex();
    result.applyFont(begin, end, fontIdx);

这应该可以连接HSSFRichTextStrings

如果您想连接 .xlsx 文件中的 XSSFRichTextStrings,过程非常相似。一个区别是XSSFRichTextString#getFontOfFormattingRun 将返回XSSFFont 而不是short 字体索引。没关系,因为在XSSFRichTextString 上调用applyFont 无论如何都需要XSSFFont。另一个区别是,如果没有为格式化运行应用字体,getFontOfFormattingRun 可能会抛出 NullPointerException,当没有应用与整个 CellStyle 的现有字体不同的字体时会发生这种情况 @987654346 @。

【讨论】:

如何绕过 XSSFRichTextStrings 的 NullPointerException? @user1007895 捕获getFontOfFormattingRun抛出的NullPointerException;这就是在该索引处没有运行格式化的情况。不要为没有应用字体的间隙创建FormattingRun。那么你就不会在新的XSSFRichTextString 中调用applyFont 来获取相应的空白。【参考方案2】:

如果您使用 XSSFRichTextStrings,则不能直接连接两个 RichTextString。

但是,您可以通过查找第二个 RichTextString 的文本值,然后使用 append 方法将该字符串值附加到应用的字体(本质上是 RichText)来间接执行此操作。

XSSFRichTextString rt1 = new XSSFRichTextString("Apache POI is");
rt1.applyFont(plainArial);
XSSFRichTextString rt2 = new XSSFRichTextString(" great!");
rt2.applyFont(boldArial);
String text = rt2.getString();

cell1.setCellValue(rt1.append(text, boldArial));

来源:

enter link description here

【讨论】:

以上是关于是否可以附加 2 个富文本字符串?的主要内容,如果未能解决你的问题,请参考以下文章

富文本编辑器-1-选型

百度的富文本编辑器Ueditor兼容问题

哪个富文本编辑器好一些

如何实现一个 Android 端的富文本编辑器

TinyMCE 一款非常不错的富文本编辑器

tinyMCE富文本编辑器禁用