Razor Page导出PDF阿拉伯语显示异常及RTL布局问题求助
解决iTextSharp导出PDF时阿拉伯语乱序及RTL布局问题
核心问题原因
阿拉伯语属于**从右到左(RTL)**的书写体系,且存在字符连写规则,普通Paragraph无法处理RTL文本的顺序反转和字形组合,直接输出会导致字符乱序。
解决步骤
1. 更换并嵌入支持阿拉伯语的字体
选择原生支持阿拉伯语的字体(如Arial Unicode MS、Windows自带的arabic.ttf),并且必须嵌入字体(将BaseFont.NOT_EMBEDDED改为BaseFont.EMBEDDED),避免不同设备上字体缺失导致的显示异常。
2. 使用RTL兼容的文本容器
放弃直接用Paragraph,改用PdfPTable+PdfPCell承载阿拉伯语文本,设置单元格的RunDirection为RTL,同时对齐方式设为右对齐。
3. 处理阿拉伯语字符连写
使用ArabicLigaturizer类(来自iTextSharp.text.pdf.draw命名空间)处理字符连写规则,确保阿拉伯语显示符合书写规范。
修改后的代码示例
替换原有的OnPostGeneratePDF方法:
using iTextSharp.text.pdf.draw; // 新增命名空间引用 public IActionResult OnPostGeneratePDF() { string invoiceNumber = Request.Form["InvNo"]; string invoiceDate = Request.Form["InvDate"]; string companyName = "شركة تجارية"; // 示例阿拉伯语公司名 using (MemoryStream memoryStream = new MemoryStream()) { // 创建文档,可根据发票布局调整页面方向 Document document = new Document(PageSize.A4); PdfWriter writer = PdfWriter.GetInstance(document, memoryStream); document.Open(); // 加载支持阿拉伯语的字体,确保路径正确 BaseFont baseFont = BaseFont.CreateFont( "c:\\windows\\fonts\\arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED // 必须嵌入字体 ); Font arabicFont = new Font(baseFont, 12, Font.NORMAL); Font arabicBoldFont = new Font(baseFont, 14, Font.BOLD); // 初始化阿拉伯语连写处理器 ArabicLigaturizer ligaturizer = new ArabicLigaturizer(); // 创建单列表格用于承载RTL文本 PdfPTable table = new PdfPTable(1); table.WidthPercentage = 100; // 占满页面宽度 // 添加公司名称(RTL) PdfPCell companyCell = new PdfPCell(new Phrase(ligaturizer.Process(companyName), arabicBoldFont)); companyCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL; companyCell.HorizontalAlignment = Element.ALIGN_RIGHT; companyCell.Border = Rectangle.NO_BORDER; companyCell.PaddingBottom = 20; table.AddCell(companyCell); // 添加发票编号 string invoiceNumText = $"رقم الفاتورة: {invoiceNumber}"; PdfPCell invoiceNumCell = new PdfPCell(new Phrase(ligaturizer.Process(invoiceNumText), arabicFont)); invoiceNumCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL; invoiceNumCell.HorizontalAlignment = Element.ALIGN_RIGHT; invoiceNumCell.Border = Rectangle.NO_BORDER; invoiceNumCell.PaddingBottom = 10; table.AddCell(invoiceNumCell); // 添加发票日期 string invoiceDateText = $"تاريخ الفاتورة: {invoiceDate}"; PdfPCell invoiceDateCell = new PdfPCell(new Phrase(ligaturizer.Process(invoiceDateText), arabicFont)); invoiceDateCell.RunDirection = PdfWriter.RUN_DIRECTION_RTL; invoiceDateCell.HorizontalAlignment = Element.ALIGN_RIGHT; invoiceDateCell.Border = Rectangle.NO_BORDER; table.AddCell(invoiceDateCell); // 将表格添加到文档 document.Add(table); document.Close(); return File(memoryStream.ToArray(), "application/pdf", "invoice.pdf"); } }
额外注意事项
- 字体路径要确保正确:可通过Windows控制面板的字体属性查看实际文件路径和文件名。
- 混合LTR(如数字、英文)和RTL文本时,iTextSharp会自动处理双向文本顺序,只需确保容器的
RunDirection设为RTL。 - 若仍有显示问题,建议升级到iText 7,新版本对RTL语言的支持更完善,API设计更友好,但需调整代码结构。
内容的提问来源于stack exchange,提问作者hhaannyy
相关产品推荐
相关产品推荐

