Itext组合框,所选选项的宽度问题
Itext combobox, width of selected option issue
我在使用 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));
请看一下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
是文本字段?我没看到你在任何地方定义它的尺寸?
我假设您想创建一个 parent 字段,例如myCombos
然后是一些孩子 combo1
, combo2
,...所以你有 myCombos.combo1
, myCombos.combo2
, 等等...
如果是这种情况,请使用createEmpty()
方法而不是createTextField()
方法。
为什么要嵌入字体?
这没有意义:
BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true)
您正在使用 BaseFont.TIMES_ROMAN
,这是一种标准 Type 1 字体。标准 Type 1 字体从不 被 iText 嵌入,因为它们应该出现在每个 reader 中。因此,createFont()
方法的 true
参数将被忽略。
是什么原因造成的?
当您定义字体时,iText 只会使用很小一部分字体数据。更具体地说:只有创建所用字符外观所需的信息 "Choose first option"。 "c" 和 "d" 在这种情况下丢失。因此,当 Adobe Reader 必须渲染第二个单词时,它会遇到缺少字符的问题。
您可以通过添加以下内容来避免这种情况:
font.setSubset(false);
或者使用完全不同的字体。
我在使用 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));
请看一下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
是文本字段?我没看到你在任何地方定义它的尺寸?
我假设您想创建一个 parent 字段,例如myCombos
然后是一些孩子 combo1
, combo2
,...所以你有 myCombos.combo1
, myCombos.combo2
, 等等...
如果是这种情况,请使用createEmpty()
方法而不是createTextField()
方法。
为什么要嵌入字体?
这没有意义:
BaseFont.createFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, true)
您正在使用 BaseFont.TIMES_ROMAN
,这是一种标准 Type 1 字体。标准 Type 1 字体从不 被 iText 嵌入,因为它们应该出现在每个 reader 中。因此,createFont()
方法的 true
参数将被忽略。
是什么原因造成的?
当您定义字体时,iText 只会使用很小一部分字体数据。更具体地说:只有创建所用字符外观所需的信息 "Choose first option"。 "c" 和 "d" 在这种情况下丢失。因此,当 Adobe Reader 必须渲染第二个单词时,它会遇到缺少字符的问题。
您可以通过添加以下内容来避免这种情况:
font.setSubset(false);
或者使用完全不同的字体。