You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:50:39