使用iText的pdf交互式表格的外观问题 [英] Appearance issues with pdf interactive forms using iText

查看:260
本文介绍了使用iText的pdf交互式表格的外观问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直关注'第8章:填写交互式表单'iText示例(代码和pdf在





我尝试使用

  fields.setFieldProperty(ndna,setfflags,PdfFormField.FF_READ_ONLY,空值); 

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



我的帮助将非常受欢迎,因为我一直在努力解决这个问题......



Anthony

解决方案

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


I have been following the 'Chapter 8: Filling out interactive forms' iText example (code and pdfs at http://itextpdf.com/examples/iia.php?id=154) and have noticed a number of appearance-related issues which also manifest themselves in the example pdfs.

The example features a list of radio buttons (classic dot within a circle) and a list of checkboxes (crossed box with a red background). So far so good. However the pdf generated after programmatically filling in these fields is visually inconsistent. The radio buttons have all reverted to squares and the selected ('Spanish') has a wingdings (?) cross within it rather than a dot. The fields are all still editable. When I select a different radio button, the previously selected radio button reverts to an empty circle. The newly selected field has changed from an empty square to a dotted circle. This can also be observed with the checkboxes.

Is there any way to fill the fields whilst preserving their original appearances?

Thanks!

EDIT - Here's a simplification of the code I use :

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();
}

Here's the ActionEvent

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) {
            }
        }
    }

Here's the 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);
            }
        }
    }
}   

And here's what happens on the server side when one clicks the button in the pdf (in 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();
        }
    }

So basically I generate a pdf with one radiogroup and a button. The button results in the pdf fields being imported and the idea is to send a 'receipt' back to the user in the form of the previously generated pdf containing the same fields with the user selection/values and import status fields (ok, missing, bad data, etc.) (which I have omitted in the above code as that part works fine). My problem is that the radio fields in the returned pdf don't look remotely like the editable ones in the original pdf (they don't even look like radio buttons anymore).

I tried using

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

and disabling form flattening by this results in the same alternate appearance in the returned pdf.

Your help would be most appreciated as I've been struggling with this for a while now...

Anthony

解决方案

This seems to be a bug on some versions of iText. I had the same problem with iTextSharp version 5.5.5 and it was solved after I upgraded to version 5.5.9. I used "nuget" to do this. Here's a link: https://www.nuget.org/packages/iTextSharp/5.5.9

这篇关于使用iText的pdf交互式表格的外观问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆