【问题标题】:How to get uniform line space for a mixed paragraph of texts and images如何为文本和图像的混合段落获得统一的行距
【发布时间】:2022-12-03 08:19:56
【问题描述】:

我正在使用 iText 7.2.1。

我想在我的文本中添加一些小图标(由代码绘制)。我发现如果在我的文本中添加小图标,很难有统一的行距。

如果一个段落的所有元素都是文本,我可以只设置SetFixedLeading(),那么无论字体大小有多大,我的行总是有相同的高度。

但是当我在段落中添加一些小图标时,SetFixedLeading() 不再有效。

我想要的就像 Microsoft Word 中的“行间距”选项。如果我给它一个固定值,它会平等对待嵌入的图像和文本,所以我总是得到固定的行距。

以下是我的代码:

using iText.Kernel.Colors;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Kernel.Pdf.Xobject;
using iText.Layout.Element;
using iText.Kernel.Geom;
using iText.Kernel.Font;
using iText.IO.Font;

namespace iTextTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var writer = new PdfWriter("test.pdf");
            var pdf_doc = new PdfDocument(writer);
            var doc = new Document(pdf_doc, iText.Kernel.Geom.PageSize.DEFAULT, false);

            // Make a text of various sizes
            var mixed_paragraph = new Paragraph();
            for (int i = 0; i < 100; i ++)
            {
                var style = new Style();
                var size = (Math.Sin(i) + 2) * 10;
                style.SetFontSize((float)size);
                mixed_paragraph.Add(new Text("A").AddStyle(style));
            }            

            // Make a 20x20 icon
            var bounds = new iText.Kernel.Geom.Rectangle(0, 0, 20, 20);
            var xobj = new PdfFormXObject(bounds);
            var pdf_canvas = new PdfCanvas(xobj, pdf_doc);
            pdf_canvas.SetFillColor(ColorConstants.RED);
            pdf_canvas.Rectangle(0, 0, 20, 20);
            pdf_canvas.Fill();
            var icon = new iText.Layout.Element.Image(xobj);
            mixed_paragraph.Add(icon);

            // Fixed leading
            mixed_paragraph.SetFixedLeading(10);

            doc.Add(mixed_paragraph);

            doc.Close();
            pdf_doc.Close();
            writer.Close();

            MessageBox.Show("OK");
        }
    }
}

这就是它的样子。第二行是正确的,但第三行的空间比固定的前导 10 多。

我需要这个,因为在我的例子中,我需要一些小的矩形图标,每个图标包含两行整数和其他信息。

这些图标的高度比我的文字高(否则很难阅读),但理论上它们仍然可以容纳,因为我的文字有足够的间距。

不幸的是,我的行间距变得不均匀。固定行距似乎不影响非文本图像,因此带有图标的行具有更宽的行间距。

我一直在考虑一种解决方法:在文本中添加空格并将图标放在这些固定位置。还是很难。我不知道如何获得这些职位。

【问题讨论】:

  • 你确定这是完整的代码吗? var canvas = new Canvas... 是一个孤立变量。运行你的代码会在 doc.Add(mixed_paragraph) 上生成 System.NullReferenceException
  • @MetroSmurf 对不起,我忘了删除那一行。我正在使用 iText 7.2.1,这段代码可以为我运行。
  • @MetroSmurf 我更新了我的代码。今天我还发现为我的图标添加一个负的上边距,比如icon.AddStyle(new Style().SetMarginTop(-20));,可以稍微缩小行高,但只能缩小一点。
  • 在带有 net6.0 项目和标准 .net 4.8 项目的 win 10 上运行您的代码。如我的第一条评论中所述,两者都因 null ref ex 而失败。
  • @MetroSmurf 这很奇怪。我正在使用 VS Community 2022、来自 NuGet 的 iText 7.2.1/7.2.4、.Net 6.0、Target OS Windows 版本 7.0。你能告诉我 null 位于何处:docmixed_paragraphAdd() 方法内部吗?

标签: c# itext itext7


【解决方案1】:

SetFixedLeading() 方法设置段落的固定行距(两行文本基线之间的距离)。但是,此方法仅影响段落内文本元素的行距,而不影响图像等其他元素。

此问题的一种解决方案是使用 SetMinHeight() 方法设置段落中每一行的最小高度,这将确保所有行(包括带有图像的行)具有相同的最小高度。如有必要,此方法将使线条变高以适应图像的高度,但整体线条间距将保持一致。

下面是一个示例,说明如何使用 SetMinHeight() 方法来实现段落中图像的统一行距:

using iText.Kernel.Colors;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Kernel.Pdf.Xobject;
using iText.Layout.Element;
using iText.Kernel.Geom;
using iText.Kernel.Font;
using iText.IO.Font;

namespace iTextTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var writer = new PdfWriter("test.pdf");
            var pdf_doc = new PdfDocument(writer);
            var doc = new Document(pdf_doc, iText.Kernel.Geom.PageSize.DEFAULT, false);

            // Make a text of various sizes
            var mixed_paragraph = new Paragraph();
            for (int i = 0; i < 100; i ++)
            {
                var style = new Style();
                var size = (Math.Sin(i) + 2) * 10;
                style.SetFontSize((float)size);
                mixed_paragraph.Add(new Text("A").AddStyle(style));
            }            

            // Make a 20x20 icon
            var bounds = new iText.Kernel.Geom.Rectangle(0, 0, 20, 20);
            var xobj = new PdfFormXObject(bounds);
            var pdf_canvas = new PdfCanvas(xobj, pdf_doc);
            pdf_canvas.SetFillColor(ColorConstants.RED);
            pdf_canvas.Rectangle(0, 0, 20, 20);
            pdf_canvas.Fill();
            var icon = new iText.Layout.Element.Image(xobj);
            mixed_paragraph.Add(icon);

            // Set the minimum height of each line in the paragraph
            mixed_paragraph.SetMinHeight(20);

            doc.Add(mixed_paragraph);

            doc.Close();
            pdf_doc.Close();
            writer.Close();

            MessageBox.Show("OK");
        }
    }
}

在本例中,我将段落中每一行的最小高度设置为20,也就是图片的高度。这可确保带有图像的行与段落中的其他行具有相同的最小高度,从而形成统一的行间距。您可以根据需要调整最小高度以获得所需的行间距。

【讨论】:

    【解决方案2】:

    要为包含文本和图像的段落实现统一的行间距,您可以使用SetMultipliedLeading()方法,它允许您指定为字体大小倍数的行高。此方法将对文本和图像应用相同的行距,使行距保持一致。

    这是一个如何使用的示例SetMultipliedLeading()为包含文本和图像的段落设置行间距的方法:

    Paragraph mixedParagraph = new Paragraph();
    
    // Add some text to the paragraph
    mixedParagraph.Add(new Text("A"));
    
    // Make a 20x20 icon
    Rectangle bounds = new Rectangle(0, 0, 20, 20);
    PdfFormXObject xobj = new PdfFormXObject(bounds);
    PdfCanvas canvas = new PdfCanvas(xobj, pdfDoc);
    canvas.SetFillColor(ColorConstants.RED);
    canvas.Rectangle(0, 0, 20, 20);
    canvas.Fill();
    Image icon = new Image(xobj);
    mixedParagraph.Add(icon);
    
    // Set the line spacing to be 1.5 times the font size
    mixedParagraph.SetMultipliedLeading(1.5f);
    
    // Add the paragraph to the document
    document.Add(mixedParagraph);
    

    这会将段落的行间距设置为字体大小的 1.5 倍,这将应用于段落中的文本和图像。这将确保行间距保持一致,即使段落包含文本和图像。

    您可以通过更改传递给SetMultipliedLeading()方法。例如,将行距设置为字体大小的 2 倍会导致行距变大,而将其设置为字体大小的 1.25 倍则会导致行距变小。尝试不同的值以找到最适合您需要的行间距。

    如果您觉得这有帮助,请考虑捐赠 BTC:178vgzZkLNV9NPxZiQqabq5crzBSgQWmvs,ETH:0x99753577c4ae89e7043addf7abbbdf7258a74697

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      相关资源
      最近更新 更多