本文讨论了在设计万能报表时,文本控件自增长和自动换行功能导致的问题及解决方案。文本换行时,空格被视为单词分隔符,导致中英文混合文本换行不一致,可能出现文本被遮盖的情况。提出了四种解决方案:一是将空格替换为非换行空格,但可能导致英文单词跨行;二是智能替换非英文单词间的空格为非换行空格;三是使用正则表达式去除非英文间的空格;四是处理特殊字符换行问题,并在末尾添加空格行以防止覆盖。
一,原理:万能报表设计时,如果文本控件勾选了自增长和自动换行,字符长度超过文本控件的宽度就会自动换行,换行时计算字符长度是以单词为单位,单词以空格进行分割,为了是保证单词不会跨行显示,往往会导致每行剩余的宽度不一致,特别是空格之间的中文也被看着一个单词,剩余的行宽度可能太大。
二,验证:什么情况下空格会导致换行和问题
1:空格导致中文换行情况:只有两个空格之间所有中文长度超过了剩余文本控件宽度才会换行,并且会导致部分覆盖问题,如下图
2:空格导致英文换行情况:只有单词的长度超过了剩余文本控件宽度才会换行,并且英文单词不会分开显示,也不会导致文本被覆盖的问题,如下图
3:中英文混合编排,中文不会影响英文的显示行数,英文也不会影响中文覆盖情况。
三,问题:通过上面示例,需要解决的问题是部分文本被遮盖的情况,先看一下不做任何处理的预览效果:
四,解决方案:有以下几种方式
方式1. 把空格替换成非换行空格,但会产生英文单词跨行显示的情况,脚本和显示效果如下:
代码:
private void label1_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) { XRLabel bindLabel = sender as XRLabel; var textArr= bindLabel.Text.ToCharArray(); int i = 0; foreach (var aitem in textArr) { if((int)aitem ==32) //换行空格转换为非换行空格( ) { textArr[i] = (char)160; } i++; } bindLabel.Text = string.Join("", textArr); }
方式2. 把空格替换成非换行空格,英文单词之间的空格不替换,不会导致单词跨行显示
代码:
using System.Collections.Generic; private void label1_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) { XRLabel bindLabel = sender as XRLabel; var textArr= bindLabel.Text.ToCharArray(); int i = 0; List<int> lstSpaceIndex = new List<int>(); foreach (var aitem in textArr) { if ((int)aitem == 32) { lstSpaceIndex.Add(i); } i++; } foreach (var spaceIndex in lstSpaceIndex) { int beforeIndex = spaceIndex - 1; int afterIndex = spaceIndex + 1; bool isLetter = false; if (beforeIndex >= 0) { var beforeAsc = (int)textArr[beforeIndex]; if (beforeAsc >= 65 && beforeAsc <= 90) { isLetter = true; } else if (beforeAsc >= 97 && beforeAsc <= 122) { isLetter = true; } } if (isLetter== true && afterIndex < textArr.Length) { var afterAsc = (int)textArr[afterIndex]; if (afterAsc >= 65 && afterAsc <= 90) { isLetter = true; } else if (afterAsc >= 97 && afterAsc <= 122) { isLetter = true; } else { isLetter = false; } } if (isLetter == false) { textArr[spaceIndex] = (char)160; } } bindLabel.Text = string.Join("", textArr); }
方式3. 去除空格,存在中英文混排的情况下,只能去除非英文之间的空格,一般使用正则表达式处理。
代码:
using System.Text.RegularExpressions; private void label1_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) { XRLabel bindLabel = sender as XRLabel; //匹配非英文字符前的空格,并替换 string lbText = Regex.Replace(bindLabel.Text, "\\s+(?![a-zA-Z])", string.Empty); //匹配非英文字符后的空格,并替换 bindLabel.Text = Regex.Replace(lbText, "(?<![a-zA-Z])\\s+", string.Empty); }
方式4.其他参考,特殊字符的处理:Https://vip.kingdee.com/article/21192
横线导致自动换行问题,
最后如果还有覆盖建议在末尾加一空格行: bindLabel.Text = bindLabel.Text +"\r\n"+" ";
加上空格还得把多行属性设置为true
推荐阅读