【问题标题】:Itext combobox, width of selected option issueItext 组合框,所选选项问题的宽度
【发布时间】:2023-03-28 17:42:01
【问题描述】:

我在使用 Itext pdf 时遇到问题。问题是,在选择了一个选项并且指针聚焦在 pdf 的另一个元素上之后,TextField 中的文本以某种方式被截断或一些字母漂浮在上面。解决方案是什么? 显示正在发生的事情的图像 代码块是

    @Override
public void writePdfElement(RankingQuestionDTO input, Document document, PdfWriter writer, PdfPTable baseTable)  {

    try{
        PdfPTable table = new PdfPTable(2);
        PdfPCell cell;
        document.add(new Paragraph(input.getText(), stylesService.getHeaderFont()));
        //Add rows with selectors
        PdfFormField selectGroup = PdfFormField.createTextField(writer, true, false, 10);
        selectGroup.setFieldName(String.format("%s", input.getUuid()));
        ArrayList<RankingAnswerDTO> possibleAnswers = input.getPossibleAnswers();
        for(int i = 0; i <input.getPossibleAnswers().size(); i++) {
            cell = new PdfPCell();
            cell.setPhrase(getPolishTablePhrase(input.getText()));
            cell.setPadding(stylesService.getPaddingCell());
            table.addCell(cell);
            cell = new PdfPCell();
            cell.setPadding(stylesService.getPaddingCell());
            cell.setCellEvent(new SelectCellEvent(String.format("%s",i), selectGroup, writer, stylesService,
                    possibleAnswers));
            cell.setMinimumHeight(stylesService.getMinimumHeight());
            table.addCell(cell);
        }
        baseTable.addCell(table);
        document.add(baseTable);
        writer.addAnnotation(selectGroup);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

    @Override
    public void cellLayout(PdfPCell cell, Rectangle position,
                       PdfContentByte[] canvases) {

    Rectangle rect = stylesService.getSelectFiledRectangle(position, sizeOfRect);
    // define the select box
    TextField tf = new TextField(writer, rect, name);

    try {
        tf.setFont(BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true));
    } catch (DocumentException | IOException e) {
        e.printStackTrace();
    }
    tf.setBackgroundColor(stylesService.getBackgroundColor());
    tf.setBorderColor(stylesService.getBorderColor());
    tf.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
    tf.setVisibility(TextField.VISIBLE_BUT_DOES_NOT_PRINT);
    tf.setBorderColor(BaseColor.GRAY);
    tf.setBorderWidth(stylesService.getFloatBorderWidth());
    tf.setFontSize(stylesService.getFieldFloatFont());
    tf.setChoices(select);
    tf.setChoiceExports(ranks);
    tf.setAlignment(Element.ALIGN_CENTER);
    tf.setOptions(TextField.MULTILINE);
    tf.setRotation(0);
    // add the select box as a field
    try {
        selectGroup.addKid(tf.getComboField());
    } catch (Exception e) {
        throw new ExceptionConverter(e);
    }
}

问题在于字体设置。 以下方法效果很好

private void initializeBaseFont() {
    try {
        baseFont = BaseFont.createFont("c:/windows/fonts/arial.ttf", BaseFont.CP1250, BaseFont.EMBEDDED);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

代替

tf.setFont(BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true));

【问题讨论】:

    标签: java combobox itext


    【解决方案1】:

    请查看ComboBoxItems 示例:

    这是单元格事件的实现:

    class SelectCellEvent implements PdfPCellEvent {
        protected PdfFormField selectGroup;
        protected String name;
        protected String[] exports;
        protected String[] options;
        protected BaseFont font;
    
        public SelectCellEvent(PdfFormField selectGroup, String name, String[] exports, String[] options) throws DocumentException, IOException {
            this.selectGroup = selectGroup;
            this.name = name;
            this.exports = exports;
            this.options = options;
            font = BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, BaseFont.NOT_EMBEDDED);
            font.setSubset(false);
        }
    
        public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
            PdfWriter writer = canvases[0].getPdfWriter();
            TextField tf = new TextField(writer, position, name);
            tf.setFont(font);
            tf.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
            tf.setVisibility(TextField.VISIBLE_BUT_DOES_NOT_PRINT);
            tf.setBorderColor(BaseColor.GRAY);
            tf.setChoiceExports(exports);
            tf.setChoices(options);
            tf.setAlignment(Element.ALIGN_CENTER);
            try {
                selectGroup.addKid(tf.getComboField());
            } catch (Exception e) {
                throw new ExceptionConverter(e);
            }
        }
    }
    

    这是 PDF 创建过程:

    public void createPdf(String dest) throws IOException, DocumentException {
        Rectangle pagesize = PageSize.LETTER;
        Document document = new Document(pagesize);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
        document.open();
        PdfPTable table = new PdfPTable(2);
        PdfPCell cell;
        //Add rows with selectors
        PdfFormField selectGroup = PdfFormField.createEmpty(writer);
        selectGroup.setFieldName("myCombos");
        String[] options = {"Choose first option", "Choose second option", "Choose third option"};
        String[] exports = {"option1", "option2", "option3"};
        table.addCell("Combobox:");
        cell = new PdfPCell();
        cell.setCellEvent(new SelectCellEvent(selectGroup, "combo1", exports, options));
        cell.setMinimumHeight(20);
        table.addCell(cell);
        document.add(table);
        writer.addAnnotation(selectGroup);
        document.close();
    }
    

    你的代码中有很多我不明白的地方。

    什么是 selectGroup?

    您似乎有几个组合框(在我的示例中只有一个),它们是名为 selectGroup 的文本字段的子项。为什么selectGroup 是一个文本字段?我没有看到你在任何地方定义它的尺寸?

    我假设您想创建一个父字段,例如myCombos,然后是一些孩子combo1combo2,......这样你就有了myCombos.combo1myCombos.combo2,等等......

    如果是这种情况,请使用createEmpty() 方法而不是createTextField() 方法。

    为什么要嵌入字体?

    这没有意义:

    BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true)
    

    您正在使用BaseFont.TIMES_ROMAN,它是标准Type 1 字体。 iText从不嵌入标准 Type 1 字体,因为它们应该存在于每个阅读器中。因此createFont() 方法的true 参数将被忽略。

    导致问题的原因是什么?

    当你定义字体时,iText 将只使用字体数据的一小部分。更具体地说:仅创建使用“选择第一个选项”的字符外观所需的信息。在这种情况下缺少“c”和“d”。因此,当 Adob​​e Reader 必须第二次渲染单词时,就会出现那些缺失字符的问题。

    您可以通过添加以下内容来避免这种情况:

    font.setSubset(false);
    

    或者使用完全不同的字体。

    【讨论】:

    • 这有点奇怪,因为当我输入tf.setFont(BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true)); 时,它就搞砸了,不管是true 还是false。但是当我使用另一种字体时,即baseFont = BaseFont.createFont("c:/windows/fonts/arial.ttf", BaseFont.CP1250, BaseFont.EMBEDDED);,一切都很好。我在page 上找到了有关该问题的更多信息我必须说非常棘手。
    • 如果你读过iText documentation,你就会明白为什么iText嵌入Standard Type 1字体(“whatsoever true or false”)。这是一个深思熟虑的设计选择。但是:现在 iText 正在讨论仅添加有关未嵌入字体子集的信息的选择。我们可能会在未来的版本中对此进行更改。
    • @BrunoLowagie 我使用这个精确的实现能够在表格的单元格内显示组合框,当我生成 pdf 时我什么也看不到
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2011-08-17
    相关资源
    最近更新 更多