首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在java中合并两个复杂的rtf(有图像或表)

如何在java中合并两个复杂的rtf(有图像或表)
EN

Stack Overflow用户
提问于 2017-05-11 19:00:31
回答 1查看 327关注 0票数 1

下面是我的代码片段,它适用于简单的rtf合并。但是它不适用于复杂的rtf合并,比如rtf有一些图像或表。有人能在这方面提供帮助吗?如何合并两个具有图像或表的rtf?

代码语言:javascript
复制
 File input1 = new File("C:\\input\\document1.rtf");
    File input2 = new File("C:\\input\\document2.rtf");
    File output = new File ("C:\\output\\res.rtf");

    FileInputStream fis1 = null;
    FileInputStream fis2 = null;
    FileOutputStream fw = null;
    try {
        fis1 = new FileInputStream(input1);
        fis2 = new FileInputStream(input2);
        fw = new FileOutputStream(output);
    } catch (IOException e1) {
        e1.printStackTrace();
    }


    try {
        Document doc1 = load(fis1);
        Document doc2 = load(fis2);
        //String contents1 = doc1.getText(0, doc1.getLength());
        //String contents2 = doc2.getText(0, doc2.getLength());
        mergeDocument((DefaultStyledDocument)doc2, (DefaultStyledDocument)doc1);
        RTFEditorKit rtf = new RTFEditorKit();
        rtf.write(fw, doc1, 0, doc1.getLength());

    } catch (IOException e) {
        e.printStackTrace();
    } catch (BadLocationException e) {
        e.printStackTrace();
    }
    finally{
        try {
            fis1.close();
            fis2.close();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static Document load(InputStream is) throws IOException {
    RTFEditorKit rtf = new RTFEditorKit();
    Document doc = rtf.createDefaultDocument();
    BufferedReader input = new BufferedReader(new InputStreamReader(is));
    try {
        rtf.read(input, doc, 0);
    } catch (BadLocationException ble) {
        throw new IOException(ble);
    }
    return doc;
}

public static void mergeDocument(DefaultStyledDocument source, DefaultStyledDocument dest) throws BadLocationException {
    ArrayList<DefaultStyledDocument.ElementSpec> specs=new ArrayList<DefaultStyledDocument.ElementSpec>();
    DefaultStyledDocument.ElementSpec spec=new DefaultStyledDocument.ElementSpec(new SimpleAttributeSet(), 
             DefaultStyledDocument.ElementSpec.EndTagType);
    specs.add(spec);
    fillSpecs(source.getDefaultRootElement(), specs, false);
    spec=new DefaultStyledDocument.ElementSpec(new SimpleAttributeSet(), DefaultStyledDocument.ElementSpec.StartTagType);
    specs.add(spec);

    DefaultStyledDocument.ElementSpec[] arr = new DefaultStyledDocument.ElementSpec[specs.size()];
    specs.toArray(arr);
    insertSpecs(dest, dest.getLength(), arr);
}

protected static void insertSpecs(DefaultStyledDocument doc, int offset, DefaultStyledDocument.ElementSpec[] specs) {
    try {
        Method m=DefaultStyledDocument.class.getDeclaredMethod("insert", new Class[] {int.class, DefaultStyledDocument.ElementSpec[].class});
        m.setAccessible(true);
        m.invoke(doc, new Object[] {offset, specs});
    } catch (Exception e) {
        e.printStackTrace();
    }
}

protected static void fillSpecs(Element elem, ArrayList<DefaultStyledDocument.ElementSpec> specs, boolean includeRoot) throws BadLocationException{
    DefaultStyledDocument.ElementSpec spec;
    if (elem.isLeaf()) {
        String str=elem.getDocument().getText(elem.getStartOffset(), elem.getEndOffset()-elem.getStartOffset());
        spec=new DefaultStyledDocument.ElementSpec(elem.getAttributes(), 
                 DefaultStyledDocument.ElementSpec.ContentType,str.toCharArray(), 0, str.length());
        specs.add(spec);
    }
    else {
        if (includeRoot) {
            spec=new DefaultStyledDocument.ElementSpec(elem.getAttributes(), DefaultStyledDocument.ElementSpec.StartTagType);
            specs.add(spec);
        }
        for (int i=0; i<elem.getElementCount(); i++) {
            fillSpecs(elem.getElement(i), specs, true);
        }

        if (includeRoot) {
            spec=new DefaultStyledDocument.ElementSpec(elem.getAttributes(), DefaultStyledDocument.ElementSpec.EndTagType);
            specs.add(spec);
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2022-09-15 08:15:28

由于lowagie.itext从2009年起就放弃了RTF(富文本格式)的相关功能。我们得从头开始。基本逻辑是

  1. 删除源文档最后一次大括号,添加一个分页。
  2. 删除目标文档头(从第一个左大括号到第二个)
  3. 唯一合并(联合)目标文档字体表、样式表、颜色表到源文档(未实现)
  4. 将左目标文档追加到源文档

http://latex2rtf.sourceforge.net/RTF-Spec-1.2.pdf

Merge RTF files

代码语言:javascript
复制
 private static byte[] mergeRTF(byte[] sourceRtf, byte[] targetRtf) {
    String sourceStr = new String(sourceRtf, StandardCharsets.UTF_8);
    String targetStr = new String(targetRtf, StandardCharsets.UTF_8);
    //source string remove last right curly brace }
    int lastRightBraceIndex = sourceStr.lastIndexOf('}');
    sourceStr = sourceStr.substring(0, lastRightBraceIndex);
    //target string remove from 1st left Curly brace to 2nd one.
    int secondLeftBraceIndex = StringUtils.ordinalIndexOf(targetStr, "{", 2);
    targetStr = targetStr.substring(secondLeftBraceIndex);
    // source append \page
    StringBuilder mergedStr = new StringBuilder(sourceStr);
    mergedStr.append(System.lineSeparator()).append("\\page").append(System.lineSeparator());
    mergedStr.append(targetStr);

    return mergedStr.toString().getBytes(StandardCharsets.UTF_8);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43923637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档