简体   繁体   English

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

[英]how to merge two complex rtf(having images or tables) in java

Below is my code snippet which works for simple rtf merge.下面是我的代码片段,适用于简单的 rtf 合并。 but it is not working for complex rtf merge like rtf having some images or tables.但它不适用于复杂的 rtf 合并,例如具有一些图像或表格的 rtf。 could anyone help on this how to merge two rtf having images or tables任何人都可以帮助解决如何合并两个具有图像或表格的 rtf

 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);
        }
    }

As lowagie.itext discard RTF(Rich Text Format) related function from 2009. we have to do this start from scratch.作为 lowagie.itext 从 2009 年开始丢弃与 RTF(富文本格式)相关的 function。我们必须从头开始。 The basic logic is基本逻辑是

  1. remove source doc last curly brace, add a page break删除源文档最后一个大括号,添加分页符
  2. delete target doc header (from first left curly brace to second one)删除目标文档 header(从第一个左大括号到第二个)
  3. uniquely merge (union) the target doc font tables, style table, color table to the source doc (not implemented)将目标文档字体表、样式表、颜色表唯一地合并(联合)到源文档(未实现)
  4. append left target doc to source doc append 左目标文档到源文档

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

Merge RTF files 合并 RTF 文件

 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);
}

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

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