万能报表空格导致文本换行问题原创
金蝶云社区-eris
eris
4人赞赏了该文章 1,440次浏览 未经作者许可,禁止转载编辑于2021年06月25日 15:45:04
summary-icon摘要由AI智能服务提供

本文讨论了在设计万能报表时,文本控件自增长和自动换行功能导致的问题及解决方案。文本换行时,空格被视为单词分隔符,导致中英文混合文本换行不一致,可能出现文本被遮盖的情况。提出了四种解决方案:一是将空格替换为非换行空格,但可能导致英文单词跨行;二是智能替换非英文单词间的空格为非换行空格;三是使用正则表达式去除非英文间的空格;四是处理特殊字符换行问题,并在末尾添加空格行以防止覆盖。

一,原理:万能报表设计时,如果文本控件勾选了自增长和自动换行,字符长度超过文本控件的宽度就会自动换行,换行时计算字符长度是以单词为单位,单词以空格进行分割,为了是保证单词不会跨行显示,往往会导致每行剩余的宽度不一致,特别是空格之间的中文也被看着一个单词,剩余的行宽度可能太大。


二,验证:什么情况下空格会导致换行和问题

1:空格导致中文换行情况:只有两个空格之间所有中文长度超过了剩余文本控件宽度才会换行,并且会导致部分覆盖问题,如下图

image.png


2:空格导致英文换行情况:只有单词的长度超过了剩余文本控件宽度才会行,并且英文单词不会分开显示,也不会导致文本被覆盖的问题,如下图

image.png



3:中英文混合编排,中文不会影响英文的显示行数,英文也不会影响中文覆盖情况。

image.png


三,问题:通过上面示例,需要解决的问题是部分文本被遮盖的情况,先看一下不做任何处理的预览效果:

image.png


四,解决方案:有以下几种方式

方式1. 把空格替换成非换行空格,但会产生英文单词跨行显示的情况,脚本和显示效果如下:

image.png


代码:

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) //换行空格转换为非换行空格(&nbsp)
        {
           textArr[i] = (char)160; 
         }
          i++;
      }
     bindLabel.Text = string.Join("", textArr);
}

方式2. 把空格替换成非换行空格,英文单词之间的空格不替换,不会导致单词跨行显示

image.png

代码:

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. 去除空格,存在中英文混排的情况下,只能去除非英文之间的空格,一般使用正则表达式处理。

image.png

代码:

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


图标赞 4
4人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!