Search code examples
c#reporting-servicesrdlc

RDLC Textbox Line Height/Line Spacing


Version: http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition

I've been looking for answers online on how to add line height or line spacing in RDLC textbox but to no avail.

I also tried <p style="line-height: 1.5;"> but it is not working when exporting to PDF. To double check this, I created a simple html file and using this style I was able to achieve my desired effect.

enter image description here

Anyway, the content of my textbox is dynamic so it could change in length. If this were fixed lines then I would simply add <br/> or Environment.NewLine as needed.

Textbox:

HTML - Interpret HTML tags as style

=Parameters!DatePrinted.Value & "<br /><br /><br /><br /><br /><br />" &
"This is to certify that <b>" & UCase(Parameters!Name.Value) & "</b> is currently enrolled in the <b>" & Parameters!CurrentTerm.Value & "</b> trimester of School Year <b>" & Parameters!CurrentSchoolYear.Value & "</b> in the <b>" & Parameters!DegreeProgram.Value & "</b> degree program at the best school in the universe. S/He was admitted into the College on the <b>" & Parameters!FirstTerm.Value & "</b> trimester of School Year <b>" & Parameters!FirstSchoolYear.Value & "</b>."
& "<br /><br /><br />" &
"This certification is being issued upon the request of <b>" & Parameters!Name.Value & "</b> for <b>" & Parameters!SpecificPurpose.Value & "</b>."
& "<br /><br /><br /><br /><br /><br />" &
"<b>Some Name</b>"
& "<br />" &
"Position"

I've tried..

=Parameters!DatePrinted.Value & "<br /><br /><br /><br /><br /><br />" &
"<p style='line-height: 1.5;'>" & 
"This is to certify that <b>" & UCase(Parameters!Name.Value) & "</b> is currently enrolled in the <b>" & Parameters!CurrentTerm.Value & "</b> trimester of School Year <b>" & Parameters!CurrentSchoolYear.Value & "</b> in the <b>" & Parameters!DegreeProgram.Value & "</b> degree program at the best school in the universe. S/He was admitted into the College on the <b>" & Parameters!FirstTerm.Value & "</b> trimester of School Year <b>" & Parameters!FirstSchoolYear.Value & "</b>."
& "</p>"
& "<br /><br /><br />" &
"<p style='line-height: 1.5;'>" &
"This certification is being issued upon the request of <b>" & Parameters!Name.Value & "</b> for <b>" & Parameters!SpecificPurpose.Value & "</b>."
& "</p>"
& "<br /><br /><br /><br /><br /><br />" &
"<b>Some Name</b>"
& "<br />" &
"Position"

Current Output:

enter image description here

With "<p style='line-height: 1.5;'>":

enter image description here

Expected Output:

enter image description here

Please ignore the indention in the expected output. I re-used the image from the Line Height in SSRS post.

If there is an existing custom code to add <br/> or Environment.NewLine for every new line within the textbox then it will surely help. I am not proficient with the custom code in reports so I would appreciate it.


Solution

  • Still no direct solution using RDLC or SSRS. I changed to using iTextSharp and was easily able to meet my requirements.

    FontFactory.RegisterDirectories();
    Font tnr = FontFactory.GetFont("Times New Roman", 12f, Font.NORMAL, BaseColor.BLACK);
    Font tnr_bold = FontFactory.GetFont("Times New Roman", 12f, Font.BOLD, BaseColor.BLACK);
    Font tnr_italic = FontFactory.GetFont("Times New Roman", 12f, Font.ITALIC, BaseColor.BLACK);
    
    List<IElement> elements = new List<IElement>();
    
    Paragraph p1 = new Paragraph(FormatUtility.FormatDate3(DateTime.Now), tnr);
    
    p1.SetLeading(0f, 2f); // This is the line height/line spacing
    
    elements.Add(p1);
    elements.Add(Chunk.NEWLINE);
    elements.Add(Chunk.NEWLINE);
    
    Paragraph p2 = new Paragraph();
    
    p2.SetLeading(0f, 2f); // This is the line height/line spacing
    p2.Add(new Chunk("This is to certify that ", tnr));
    p2.Add(new Chunk(name.ToUpper(), tnr_bold));
    p2.Add(new Chunk(" is currently enrolled in the ", tnr));
    .
    .
    .
    p2.Add(new Chunk(" trimester of School Year ", tnr));
    p2.Add(new Chunk(currentSchoolYearTxt, tnr_bold));
    p2.Add(new Chunk(" in the ", tnr));
    p2.Add(new Chunk(degreeProgram, tnr_bold));
    p2.Add(new Chunk(" degree program at the best school in the universe. S/He was admitted into the College on ", tnr));
    .
    .
    .
    p2.Add(new Chunk(" trimester of School Year ", tnr));
    p2.Add(new Chunk(firstSchoolYearTxt, tnr_bold));
    p2.Add(new Chunk(".", tnr));
    
    elements.Add(p2);
    elements.Add(Chunk.NEWLINE);
    
    Paragraph p3 = new Paragraph();
    
    p3.SetLeading(0f, 2f); // This is the line height/line spacing
    p3.Add(new Chunk("This certification is being issued upon the request of ", tnr));
    p3.Add(new Chunk(name, tnr_bold));
    p3.Add(new Chunk(" for ", tnr));
    p3.Add(new Chunk(specificPurpose, tnr_bold));
    p3.Add(new Chunk(".", tnr));
    
    elements.Add(p3);
    elements.Add(Chunk.NEWLINE);
    elements.Add(Chunk.NEWLINE);
    elements.Add(new Paragraph("Someone Name", tnr_bold));
    elements.Add(new Paragraph("Position", tnr));
    
    byte[] renderedBytes = CreatePDF(PageSize.LETTER, elements, 72f, 72f, 216f, 72f);
    

    And

    private byte[] CreatePDF(Rectangle pageSize, IList<IElement> elements, float marginLeft = 0f, float marginRight = 0f, float marginTop = 0f, float marginBottom = 0f)
    {
        byte[] renderedBytes = null;
    
        using (MemoryStream ms = new MemoryStream())
        {
            // Margins: 72f = 1 inch
            using (Document document = new Document(pageSize, marginLeft, marginRight, marginTop, marginBottom))
            {
                PdfWriter pdf = PdfWriter.GetInstance(document, ms);
    
                document.Open();
    
                foreach (IElement element in elements)
                {
                    document.Add(element);
                }
    
                document.Close();
    
                renderedBytes = ms.ToArray();
    
                return renderedBytes;    
            }
        }
    }
    

    I almost achieved the similar effect on RDLC using the following:

    string content = "Date <br/><br/><br/><br/><br/> This is to certify that <b>(NAME)</b> is currently enrolled in the <b>(CurrentTerm)</b> trimester of School Year <b>(CurrentSY)</b> in the <b>(Degree Program)</b> degree program at the best school in the universe. S/He was admitted into the College on <b>(FirstTerm)</b> trimester of School Year <b>(FirstSY)</b>. <br/><br/><br/> This certification is being issued upon the request of <b>(Name)</b> for <b>(specific purpose/s)</b>. <br/><br/><br/><br/><br/> <b>Some Name</b> <br/> Position";
    
    content = content
            .Replace("(NAME)", name.ToUpper()); // Replace necessary strings with variable values
    
    content = SplitByBreak(content, 85);
    

    And

    public static string SplitByBreak(string text, int length)
    {
        List<string> ignoreList = new List<string>()
        {
            "<b>", 
            "</b>", 
            "<i>", 
            "</i>"
        };
        string br = "<br/>";
        string newText = string.Empty;
        string newLine = string.Empty;
    
        // Make sure that <br/> is the standard break.
        text = text.Replace("<br>", br);
    
        string[] split = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    
        for (int i = 0; i < split.Length; i++)
        {
            string testLine = string.Format("{0} {1}", newLine, split[i]).Trim();
            string temp = testLine;
            int lastIndexBr = testLine.LastIndexOf(br);
    
            // Count from the last index of <br/>.
            if (lastIndexBr >= 0)
            {
                temp = temp.Substring(lastIndexBr + br.Length);
            }
    
            // Do not include the length from the ignore list. -Eph 10.19.2018
            foreach (string s in ignoreList)
            {
                temp = temp.Replace(s, string.Empty);
            }
    
            if (temp.Length > length)
            {
                newText = string.Format("{0} {1} {2}{2}", newText, newLine, br).Trim();
                newLine = split[i];
            }
            else
            {
                testLine = string.Format("{0} {1}", newLine, split[i]).Trim();
                newLine = testLine;
            }
        }
    
        newText = string.Format("{0} {1}", newText, newLine).Trim();
    
        return newText;
    }
    

    This function I created is good and all but it simply adds <br/><br/> for every n string in length while ignoring the tags inside the ignoreList. This is useful only on fonts that have the same character width which isn't gonna work for me.