【问题标题】:itextsharp auto font size and Linebreak only on Spacesitextsharp 自动字体大小和 Linebreak 仅在 Spaces 上
【发布时间】:2018-05-03 18:13:01
【问题描述】:

我有一个 itextsharp 表,具有严格的单元格高度和宽度。 然后我得到一个字数和工作长度可能不同的字符串。 如何自动将字体大小设置为尽可能大,并且只允许在单词结束后中断,就像在 WPF 的 Viewboxes 中一样。

目前我正在处理这个:

Cell.AddElement(new Paragraph(text, new Font(Font.FontFamily.COURIER, 
Convert.ToInt32(FZ), 1)){Alignment = Element.ALIGN_CENTER});
            Cell.VerticalAlignment = Element.ALIGN_MIDDLE;
            Cell.HorizontalAlignment = Element.ALIGN_MIDDLE;
            Cell.Padding = 4;
            Cell.FixedHeight = Utilities.MillimetersToPoints(46);
            return Cell;

FZ 是我直接从视图框中获取的字体大小,但直接转换不起作用

提前致谢!

【问题讨论】:

  • 您(可以)知道每个单元格的宽度(例如w),因为该宽度是在您创建PdfPTable 对象时定义的。您应该使用该宽度来确定字体大小。您知道要添加哪些文本,因此您可以计算将文本绘制为 字形空间 中的值所需的宽度(例如 wg)。根据wwg的值,可以计算出字体大小。
  • 我知道我之前已经解释过所有这些。请阅读我对重复问题的回答。它解释了什么是字形空间,以及如何根据stringBaseFont 和可用宽度确定字体大小。
  • 这不是重复的。你读过我的整个问题吗?你也没有说任何关于 Linebreaks midword..
  • 好的,我重新打开了这个问题。至于“单词结束后允许中断,就像在 WPF 的 Viewboxes 中一样”,您需要解释您的意思,因为我不知道“WPF 的 Viewboxes”是什么。这个问题非常不清楚。也许我应该对它投反对票,而不是给它一个近距离投票。
  • 如果您在视图框内有一个文本块,文本将缩小而不是超出视图框边界。

标签: wpf itext font-size viewbox


【解决方案1】:

我创建了一个独立的应用程序,其中包含许多 "test""test\ntest""test test test test" 等...单元格。结果如下所示:

我做了几个假设:

  • 我假设单元格是使用String 值创建的。在内部,这将产生一个包含单个ParagraphList。这个Paragraph 将包含一个Text 对象。
  • 我假设没有定义字体,这就是我引入默认字体 (Helvetica) 的原因。
  • 我假设没有定义前导,因此我引入了 1 的倍增前导。
  • 我假设没有定义填充,因此我引入了 1 的填充

这是我的代码:

import java.io.File;
import java.io.IOException;

import com.itextpdf.io.font.FontProgram;
import com.itextpdf.io.font.FontProgramFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.IRenderer;

public class FitCell {

    public static final String[] TEST = {
        "test",
        "test test test test test test test",
        "test test",
        "test",
        "test test test test\ntest test test test test test test test test test test",
        "test",
        "test",
        "test",
        "test\ntest\ntest\ntest",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test\ntest",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test",
        "test test test test test test test test test test test test test test"
    };

    private class FitContentCellRenderer extends CellRenderer {
        public FitContentCellRenderer(Cell modelElement) {
            super(modelElement);
            try {
                // We assume that the Cell is created by passing a String
                // This means that the Cell consists of one Paragraph
                Paragraph p = (Paragraph)modelElement.getChildren().get(0);
                // And that the Paragraph has one Text object
                Text t = (Text)p.getChildren().get(0);
                // Using the default font
                FontProgram f = FontProgramFactory.createFont();

                // We get the content from the Text object
                String content = t.getText();
                // Define a default font size (to make sure that you don't have text that is excessively big).
                float fs = 100;
                // Define a font size depending on the number of lines and the height
                int[] fontBbox = f.getFontMetrics().getBbox();
                int fh = (fontBbox[2] - fontBbox[1]);
                float padding = 1;
                modelElement.setPadding(padding);
                float ch = modelElement.getHeight() - 2 * padding;
                String text[] = content.split("\\r\\n|\\n|\\r");
                fs = Math.min(fs, ch / (fh * text.length) * FontProgram.UNITS_NORMALIZATION);
                // Loop over all the lines
                PdfFont font = PdfFontFactory.createFont(f);
                float cw = modelElement.getWidth().getValue() - 2 * padding;
                for (String l : text) {
                    float w = font.getWidth(l, 1);
                    fs = Math.min(fs, cw / w);
                }
                p.setFontSize(fs);
                p.setMultipliedLeading(1);
            }
            catch(IOException ioe) {
                // occurs when font program can't be created; this never happens
            }
        }
        @Override
        public IRenderer getNextRenderer(){
            return new FitContentCellRenderer(getModelElement());
        }
    }

    private class FitContentCell extends Cell {
        public FitContentCell() {
            super();
            this.setWidth(50);
        }

        @Override
        protected IRenderer makeNewRenderer() {
            return new FitContentCellRenderer(this);
        }
    }

    public static final String DEST = "results/tables/cell_fit_content.pdf";

    public static void main(String args[]) throws IOException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FitCell().createPdf(DEST);
    }

    public void createPdf(String dest) throws IOException {
        PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
        Document document = new Document(pdf);
        Table table = new Table(new float[]{1, 1, 1, 1, 1, 1, 1});
        int testcount = 0;
        for (int i = 0; i < 70; i++) {
            if (testcount >= TEST.length) {
                testcount = 0;
            }
            table.addCell(new FitContentCell().add(TEST[testcount++]).setHeight(20 + 10 * (i / 10)));
        }
        document.add(table);
        document.close();
    }
}

在这段代码中,我在一个名为FitCell 的子类中更改了Cell 对象的行为。 FitCell 的行为是通过覆盖 CellRenderer 来改变的。

实际上,我并没有真正改变渲染器的行为,而是在创建渲染器实例的那一刻(在其他任何事情发生之前)改变了一些东西。我为单元格定义了一个填充,我为Paragraph 定义了一个字体和一个前导,我计算了Paragraph 的字体大小,以便文本适合单元格。我首先定义了一个 100 的字体大小(这是巨大的),但是没有一个内容最终会有 100 的字体大小,因为我首先要确保所有的文本都适合单元格的高度;然后我确保所有文本都适合单元格的宽度。

结果是所有文本都适合单元格。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多