如何使用RTF Parser Kit提取RTF中的内嵌图片到File列表?
问题描述
我从SQL Server数据库中读取某列的RTF格式数据,目前已经用RTF Parser Kit成功将RTF转换为纯文本,代码如下:
InputStream is = new ByteArrayInputStream(input.getBytes()); StringTextConverter converter = new StringTextConverter(); converter.convert(new RtfStreamSource(is)); input = converter.getText();
但部分RTF内容里包含内嵌图片,请问能不能用RTF Parser Kit把这些图片提取到ArrayList<File> files = new ArrayList<>();中?
示例图片:
对应的RTF片段(完整内容过长,仅展示部分):
{\rtf1\ansi\ansicpg1253\uc1\deff1\adeff1\deflang0\deflangfe0\adeflang0{\fonttbl {\f0\fswiss\fcharset0\fprq2{\*\panose 020B0604020202020204}Arial;} {\f1\fswiss\fcharset161\fprq2 Arial Greek;} {\f2\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}} {\colortbl;\red0\green0\blue0;} {\stylesheet{\s0\ltrpar\itap0\nowidctlpar\ql\li0\ri0\lin0\rin0\cbpat0\rtlch\af1\afs24\ltrch\f1\fs24 [Normal];}{\*\cs10\additive Default Paragraph Font;}} {\info {\*\txInfo{\txVer 24.0.712.500}}} \paperw12240\paperh15840\margl1138\margt1138\margr1138\margb1138\deftab1134\widowctrl\lytexcttp\formshade\sectd \headery567\footery567\pgwsxn12240\pghsxn15840\marglsxn1138\margtsxn1138\margrsxn1138\margbsxn1138\pgbrdropt32\pard\ltrpar\itap0\nowidctlpar\ql\li0\ri0\lin0\rin0\plain\rtlch\af0\afs20\alang1033\ltrch\f0\fs20\lang1033\langnp1033\langfe1033\langfenp1033 Hello, \par\par This is an example!\par\par {\shp{\*\shpinst\shpleft0\shptop0\shpright7500\shpbottom3450\shpfhdr0\shpbxcolumn\shpbxignore\shpbypara\shpbyignore\shpwr2\shpwrk0\shpz0\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn wzName}{\sv _tx_id_1_}}{\sp{\sn pib}{\sv {\pict\jpegblip\picw13229\pich6085\picwgoal7500\pichgoal3450\picscalex100\picscaley100 ffd8ffe000104a46494600010101006000600000ffe101024578696600004d4d002a000000080007011a0005000000010000 0062011b0005000000010000006a012800030000000100020000013100020000001100000072013b00020000000700000084 ff0011dbd85aebb65a6ead089ededb55b7d2f51d5b4f8af6253b654b4d4af61071b6e24fbc403d62800a002800a002800a00 2800a002800a002800a002800a002800a002800a002800a002800a002800a002800a002800a002800a002800a002800a0028 00a002800a002800a002800a002800a002800a002803ffd9}}}\par }
解决方案
可以用RTF Parser Kit提取内嵌图片,核心思路是自定义Converter,重写图片处理方法,解析图片数据并保存为文件后加入目标ArrayList。
步骤1:自定义图片提取转换器
继承StringTextConverter,保留原文本转换功能的同时添加图片存储逻辑:
import com.rtfparserkit.parser.IRtfParser; import com.rtfparserkit.parser.RtfParser; import com.rtfparserkit.parser.IRtfSource; import com.rtfparserkit.converter.StringTextConverter; import com.rtfparserkit.rtf.Command; import com.rtfparserkit.rtf.RtfPictureData; import java.io.*; import java.util.ArrayList; import java.util.List; public class RtfTextAndImageConverter extends StringTextConverter { private List<File> imageFiles; private File outputDir; // 初始化时指定图片输出目录和存储列表 public RtfTextAndImageConverter(File outputDir, List<File> imageFiles) { this.outputDir = outputDir; this.imageFiles = imageFiles; // 创建输出目录(不存在则自动生成) if (!outputDir.exists()) { outputDir.mkdirs(); } } // 重写处理图片的方法 @Override public void processPicture(RtfPictureData pictureData) { super.processPicture(pictureData); // 保留原文本转换的占位逻辑(可选) // 获取图片格式和原始二进制数据 Command pictureType = pictureData.getType(); byte[] imageBytes = pictureData.getData(); // 根据RTF图片命令匹配对应文件后缀 String fileExt = switch (pictureType.getCommandName()) { case "jpegblip" -> ".jpg"; case "pngblip" -> ".png"; case "emfblip" -> ".emf"; case "wmfblip" -> ".wmf"; default -> ".bin"; // 未知格式用通用后缀 }; // 生成唯一文件名,避免重复覆盖 String fileName = "rtf_image_" + System.currentTimeMillis() + fileExt; File imageFile = new File(outputDir, fileName); // 写入图片数据到本地文件 try (FileOutputStream fos = new FileOutputStream(imageFile)) { fos.write(imageBytes); imageFiles.add(imageFile); // 将生成的文件对象加入目标列表 } catch (IOException e) { e.printStackTrace(); } } }
步骤2:使用自定义转换器处理RTF
替换原有的StringTextConverter,传入图片输出目录和目标ArrayList即可完成文本转换+图片提取:
public static void main(String[] args) throws IOException { String rtfContent = "从SQL Server读取的RTF字符串"; // 替换为实际获取的RTF内容 List<File> files = new ArrayList<>(); File imageOutputDir = new File("./extracted_images"); // 自定义图片保存目录 InputStream is = new ByteArrayInputStream(rtfContent.getBytes()); IRtfSource source = new com.rtfparserkit.parser.RtfStreamSource(is); RtfTextAndImageConverter converter = new RtfTextAndImageConverter(imageOutputDir, files); IRtfParser parser = new RtfParser(); parser.parse(source, converter); // 获取转换后的纯文本 String plainText = converter.getText(); // 查看提取到的图片列表 System.out.println("共提取到" + files.size() + "张图片"); for (File f : files) { System.out.println("图片路径:" + f.getAbsolutePath()); } }
注意事项
- 确保使用RTF Parser Kit的最新稳定版,避免版本兼容问题
- 遇到未知图片格式时,可根据实际需求扩展格式匹配逻辑
- 文件名生成规则可结合业务场景调整(比如加入图片在RTF中的位置标识)
- 需完善IO异常处理逻辑,避免因文件写入失败导致程序中断
内容的提问来源于stack exchange,提问作者yaylitzis
相关产品推荐
相关产品推荐

