下面是我的代码片段,适用于简单的 rtf 合并。 但它不适用于复杂的 RTF 合并,例如具有一些图像或表格的 RTF。 谁能帮忙 如何合并两个具有图像或表格的 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);
}
}
由于 lowagie.itext 从 2009 年开始丢弃 RTF(富文本格式(相关功能。我们必须从头开始。基本逻辑是
- 删除源文档最后一个大括号,添加分页符
- 删除目标文档标题(从第一个左大括号到第二个大括号(
- 唯一地将目标文档字体表、样式表、颜色表合并(联合(到源文档(未实现(
- 将左侧目标文档附加到源文档
http://latex2rtf.sourceforge.net/RTF-Spec-1.2.pdf
合并 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);
}