WinForms RichTextBox带颜色文本存PDF(iTextSharp)丢失颜色问题
解决RichTextBox带颜色内容导出PDF丢失格式的问题
嘿,我一眼就看出问题在哪了——你现在用txt_result.Text拿的是纯文本,RichTextBox里设置的颜色、样式这些格式信息根本没被带出来,导出PDF当然全是黑色啦!得换个思路,读取RichTextBox的RTF格式内容,再解析里面的样式对应到iTextSharp里才行。
为啥颜色会丢?
RichTextBox.Text这个属性只会返回不带任何格式的纯文本,你之前在WinForms里设置的行颜色、字体样式这些都存在RTF格式里,所以必须用txt_result.Rtf来获取完整的带格式内容。
具体解决步骤
1. 先把内容获取方式改了
把原来的string str = txt_result.Text;换成:
string rtfContent = txt_result.Rtf;
2. 解析RTF里的颜色表和文本
RTF里有个\colortbl块存着所有用到的颜色,还有\cfN标记(N是颜色表的索引)来标记文本用哪个颜色。我写了两个简化的解析方法,你可以直接用:
using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; using System.Text.RegularExpressions; // 解析RTF里的颜色表,转成iTextSharp能用的BaseColor字典 private Dictionary<int, BaseColor> ParseRtfColorTable(string rtf) { var colorTable = new Dictionary<int, BaseColor>(); // 匹配颜色表的正则 var colorMatch = Regex.Match(rtf, @"\\colortbl(.*?);", RegexOptions.Singleline); if (colorMatch.Success) { var colorEntries = colorMatch.Groups[1].Value.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < colorEntries.Length; i++) { var parts = colorEntries[i].TrimStart('\\').Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length >= 3 && int.TryParse(parts[0].Substring(1), out int red) && int.TryParse(parts[1].Substring(1), out int green) && int.TryParse(parts[2].Substring(1), out int blue)) { // RTF颜色值是0-255,直接转成BaseColor colorTable.Add(i + 1, new BaseColor(red, green, blue)); } } } // 加个默认黑色,防止找不到对应颜色 colorTable.Add(0, BaseColor.BLACK); return colorTable; } // 把带颜色标记的RTF文本转成PDF的Paragraph对象 private Paragraph ParseRtfTextToParagraph(string rtf, Dictionary<int, BaseColor> colorTable) { var paragraph = new Paragraph(); // 先去掉一些无关的RTF格式标记(比如段落对齐、缩进) var cleanRtf = Regex.Replace(rtf, @"\\pard|\\sa\d+|\\li\d+|\\fi\d+|\\qc|\\qr", "", RegexOptions.IgnoreCase); // 匹配每个颜色块和对应的文本 var matches = Regex.Matches(cleanRtf, @"\\cf(\d+)(.*?)(?=\\cf|\Z)", RegexOptions.Singleline); foreach (Match match in matches) { if (int.TryParse(match.Groups[1].Value, out int colorIndex) && colorTable.TryGetValue(colorIndex, out BaseColor color)) { string text = match.Groups[2].Value; // 处理RTF的转义字符:\par换成换行,\\换成\,\'换成' text = Regex.Replace(text, @"\\par", "\n"); text = Regex.Replace(text, @"\\\\", "\\"); text = Regex.Replace(text, @"\\'", "'"); // 创建带颜色的Chunk,加到段落里 var chunk = new Chunk(text, new Font(Font.FontFamily.HELVETICA, 12, Font.NORMAL, color)); paragraph.Add(chunk); } } return paragraph; }
3. 修改导出PDF的代码
把你原来的导出逻辑换成下面的,用上面的方法解析后再生成PDF:
SaveFileDialog dlg = new SaveFileDialog(); dlg.Filter = "pdf files (*.pdf)|*.pdf"; dlg.Title = "Als PDF speichern"; if (dlg.ShowDialog() == DialogResult.OK) { string path = dlg.FileName; string rtfContent = txt_result.Rtf; // 创建并写入PDF using (FileStream fs = new FileStream(path, FileMode.Create)) { Document document = new Document(); PdfWriter.GetInstance(document, fs); document.Open(); // 解析颜色表和文本,加到文档里 var colorTable = ParseRtfColorTable(rtfContent); Paragraph paragraph = ParseRtfTextToParagraph(rtfContent, colorTable); document.Add(paragraph); document.Close(); } }
小提示
- 这个是简化版,只处理了颜色,如果你的RichTextBox还有粗体、斜体、字体大小这些样式,得扩展正则表达式去匹配对应的RTF标记(比如
\b是粗体,\i是斜体),然后在创建Font的时候设置对应的样式。 - 别忘了通过NuGet安装iTextSharp包哦!
内容的提问来源于stack exchange,提问作者clem995
相关产品推荐
相关产品推荐

