gpt4 book ai didi

java - 使用 iText 的 pdf 交互式表单的外观问题

转载 作者:太空宇宙 更新时间:2023-11-04 13:22:54 32 4
gpt4 key购买 nike

我一直在关注“第 8 章:填写交互式表单”iText 示例(代码和 pdf 位于 http://itextpdf.com/examples/iia.php?id=154 ),并注意到一些与外观相关的问题,这些问题也体现在示例 pdf 中。

该示例具有单选按钮列表(圆圈内的经典点)和复选框列表(带有红色背景的交叉框)。到目前为止,一切都很好。然而,以编程方式填写这些字段后生成的 pdf 在视觉上不一致。单选按钮已全部恢复为正方形,并且选定的(“西类牙语”)内部有一个十字形(?)十字而不是点。这些字段仍然可以编辑。当我选择不同的单选按钮时,之前选择的单选按钮将恢复为空圆圈。新选择的字段已从空方 block 变为虚线圆圈。这也可以通过复选框观察到。

有什么办法可以在填充字段的同时保留其原始外观吗?

谢谢!

编辑 - 这是我使用的代码的简化:

public void buildPdf() throws Exception {

Document document = new Document(PageSize.A4);

File file = new File("/test.pdf");
final PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));

document.open();

PdfPCell cell = new PdfPCell();

PdfRadioGroupTable group = new PdfRadioGroupTable("ndna", Arrays.asList("Not Available", "Not Applicable"), writer, Locale.ENGLISH, DEFAULT);

cell.addElement(group);

PdfPTable table = new PdfPTable(1);

table.addCell(cell);

cell = new PdfPCell();

cell.setCellEvent(new ActionEvent(writer, "http://localhost:8080/entrypointpdf"));

table.addCell(cell);

document.add(table);

group.addAnnotations();

document.close();
}

这是 Action 事件

class ActionEvent implements PdfPCellEvent {

private PdfWriter writer;
private String submissionUrl;

public ActionEvent(PdfWriter writer, String submissionUrl) {
this.writer = writer;
this.submissionUrl = submissionUrl;
}

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

PushbuttonField submit = new PushbuttonField(writer, position, "submit") {

@Override
public PdfFormField getField() throws IOException, DocumentException {

PdfFormField field = super.getField();

field.setAction(PdfAction.createSubmitForm(submissionUrl, null, 0));

return field;
}
};
submit.setText("CLICK ME");
submit.setTextColor(BaseColor.BLUE);
submit.setFont(DEFAULT.getCalculatedBaseFont(false));
submit.setVisibility(PushbuttonField.VISIBLE);

try {
writer.addAnnotation(submit.getField());
} catch (Exception ignore) {
}
}
}

这是 PdfRadioGroupTable

public class PdfRadioGroupTable extends PdfPTable {

private PdfWriter writer;
public PdfFormField radioGroup;

public PdfRadioGroupTable(String name, List<String> choices, PdfWriter writer, Locale locale, Font font) {
super(2);

this.writer = writer;

setWidthPercentage(100);
try {
setTotalWidth(new float[] { 14, 400 });
} catch (DocumentException ignore) {
}

radioGroup = PdfFormField.createRadioButton(writer, true);
radioGroup.setFieldName(name);

PdfPCell cell;

for (String choice : choices) {
cell = new PdfPCell();

cell.setBorder(0);
cell.setPaddingBottom(5);

cell.setUseAscender(true);
cell.setUseDescender(true);
cell.setVerticalAlignment(PdfPCell.ALIGN_CENTER);

cell.setCellEvent(new RadioCellEvent(radioGroup, choice));

addCell(cell);

cell = new PdfPCell();

cell.setBorder(0);

cell.setPaddingBottom(5);
cell.setPaddingLeft(6);

cell.setUseAscender(true);
cell.setUseDescender(true);
cell.setVerticalAlignment(PdfPCell.ALIGN_CENTER);

cell.addElement(new Phrase(choice), font));

addCell(cell);
}
}

class RadioCellEvent implements PdfPCellEvent {

protected PdfFormField radioGroup;
protected String value;

public RadioCellEvent(PdfFormField radioGroup, String value) {
this.radioGroup = radioGroup;
this.value = value;
}

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

RadioCheckField radio = new RadioCheckField(writer, position, null, value);

radio.setChecked(false);

radio.setBorderColor(GrayColor.GRAYBLACK);
radio.setBackgroundColor(GrayColor.GRAYWHITE);
radio.setCheckType(RadioCheckField.TYPE_CIRCLE);

try {
PdfFormField field = radio.getRadioField();

writer.addAnnotation(field);
radioGroup.addKid(field);

} catch (Exception exception) {
throw new ExceptionConverter(exception);
}
}
}
}

以下是当单击 pdf 中的按钮(在 acrobat 中)时服务器端发生的情况:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException {

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=\"your.pdf\"");

try {
FdfReader fdf = new FdfReader(request.getInputStream());

File pdfFile = new File("/test.pdf");

InputStream is = new FileInputStream(pdfFile);

PdfReader reader = new PdfReader(is);

File resultFile = new File(System.currentTimeMillis() + "_" + pdfFile.getName());
FileOutputStream out = new FileOutputStream(resultFile);

PdfStamper stamper = new PdfStamper(reader, out);

AcroFields fields = stamper.getAcroFields();
fields.setFields(fdf);

// EXTRACT VALUES HERE

stamper.setFormFlattening(true);

stamper.close();
reader.close();

ByteArrayOutputStream bos = new ByteArrayOutputStream();

bos.write(FilesUtilities.read(resultFile));

OutputStream os = response.getOutputStream();
bos.writeTo(os);
os.flush();

} catch (Exception e) {
e.printStackTrace();
}
}

所以基本上我生成了一个带有一个单选组和一个按钮的 pdf 文件。该按钮导致 pdf 字段被导入,其想法是以先前生成的 pdf 的形式将“收据”发送回用户,其中包含与用户选择/值和导入状态字段相同的字段(正常、丢失、错误数据等)(我在上面的代码中省略了该部分,因为该部分工作正常)。我的问题是,返回的 pdf 中的单选字段看起来与原始 pdf 中的可编辑字段完全不同(它们甚至不再看起来像单选按钮)。

Before

Returned

我尝试使用

fields.setFieldProperty("ndna", "setfflags", PdfFormField.FF_READ_ONLY, null);

并通过此禁用表单展平会导致返回的 pdf 中出现相同的替代外观。

非常感谢您的帮助,因为我已经为此苦苦挣扎了一段时间......

安东尼

最佳答案

这似乎是某些版本的 iText 上的错误。我在 iTextSharp 5.5.5 版本中遇到了同样的问题,升级到 5.5.9 版本后解决了。我用“nuget”来做到这一点。这是一个链接:https://www.nuget.org/packages/iTextSharp/5.5.9

关于java - 使用 iText 的 pdf 交互式表单的外观问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32906739/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com