1. 程式人生 > >itext操作pdf表單域

itext操作pdf表單域

寫這個純屬是為了總結最近所學的知識,也是為了給後面用的到人的一些幫助。因為自己在國內查找了不少資料,但都不是自己想要的。

背景:建立合同時,需要填寫某些文字域、radio、checkbox還有最後需要對合同簽名,所以需要研究使用,而不是採用外部編輯器。

itext簡介

iText是一種生成PDF報表的Java元件。通過在伺服器端使用Jsp或JavaBean生成PDF報表

因為itext版本太多,我這裡採用的是5.5.3,只供讀者參考。

表單域

檢視例子後發現,無法符合我的需求,我是讀取上傳的pdf模板,並修改其表單域,在寫入到新的檔案中,可以理解為

讀取a
——操作a的副本--寫入b

PdfStamper很好的解決了這一問題,我們看看api的介紹
Applies extra content to the pages of a PDF document. This extra content can be all the objects allowed in PdfContentByte including pages from other Pdfs. The original PDF will keep all the interactive elements including bookmarks, links and form fields.

//test為原始檔流 理解為上文的檔案a
PdfReader reader = new PdfReader(dest);
//outputStream 理解為上文的檔案b
PdfStamper stamper = new PdfStamper(reader, outputStream
); 

text域

 public static void creatTextField(PdfStamper pdfStamper, PdfReader reader) throws IOException, DocumentException {
        PdfWriter writer = pdfStamper.getWriter
(); PdfFormField form = PdfFormField.createEmpty(writer); //普通文字框 TextField field = new TextField(writer, new Rectangle(200, 200, 400, 300), "text"); field.setOptions(TextField.MULTILINE); //防止讀取pdf文件時,就是有旋轉角度的 field.setRotation(reader.getPageRotation(1)); //有些情況下,頁數問題可以在這裡設定,優先順序最高 field.getTextField().setPlaceInPage(1); form.addKid(field.getTextField()); // file.setOptions(TextField.VISIBLE);//文字域可見(相對於文字域是否高亮) // file.setOptions(TextField.HIDDEN);//文字域不可見 // file.setOptions(TextField.VISIBLE_BUT_DOES_NOT_PRINT);//該欄位可見,但不列印。 // file.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//該欄位不可見,但不列印。 // file.setOptions(TextField.HIDDEN_BUT_PRINTABLE);//該欄位不可見,但不列印。 // file.setOptions(TextField.READ_ONLY);//只讀 // file.setOptions(TextField.REQUIRED);//該欄位在通過提交表單操作匯出時必須具有值。 // file.setOptions(TextField.MULTILINE);//規定區域內可以換行顯示 // file.setOptions(TextField.DO_NOT_SCROLL);//文字域不會有滾動條,對於單行欄位為水平,對於多行欄位為垂直,一旦區域滿了,將不會再接受任何文字。 // file.setOptions(TextField.PASSWORD);//該欄位用於輸入安全密碼,該密碼不應該被可視地顯示在螢幕上。 // file.setOptions(TextField.FILE_SELECTION);//個人理解好像是上傳檔案,不是很理解 // file.setOptions(TextField.DO_NOT_SPELL_CHECK);//無拼寫檢查 // file.setOptions(TextField.EDIT);//如果設定組合框包括一個可編輯的文字框以及一個下拉列表;如果清楚,它只包括一個下拉列表。這個標誌只對組合欄位有意義。 // file.setOptions(TextField.MULTISELECT);//不管列表是否可以有多個選擇。僅適用於/ ch列表欄位,而不適用於組合框。 // file.setOptions(TextField.COMB);//組合框標誌。 pdfStamper.addAnnotation(form,1); }

radio

需要注意的是,radio是一組一組的。

public static void creatRadioCheckField(PdfStamper pdfStamper,PdfReader reader) throws IOException, DocumentException {
        PdfWriter writer = pdfStamper.getWriter();
         //radio框
         // PdfFormField radioForm=PdfFormField.createRadioButton(writer, true);
         PdfFormField  radiogroup=PdfFormField.createRadioButton(writer, true);

        radiogroup.setFieldName("test");
        RadioCheckField bt=new RadioCheckField(writer, new Rectangle(100, 500, 120, 518), null, "v1");

        // bt.setCheckType(RadioCheckField.TYPE_CROSS);//X型
        // bt.setCheckType(RadioCheckField.TYPE_DIAMOND);//菱形
        // bt.setCheckType(RadioCheckField.TYPE_SQUARE);//正方形
        // bt.setCheckType(RadioCheckField.TYPE_STAR);//星星圖案
        // checkField.setCheckType(RadioCheckField.TYPE_CHECK);//checkbox
        bt.setCheckType(RadioCheckField.TYPE_CIRCLE);//圓型 radio
        bt.setBackgroundColor(new GrayColor(0.8f));//這個顏色看起來比較舒服,建議只採用設定背景顏色
        // bt.setChecked(true);//設定radio是否被選中
        PdfFormField f1 = bt.getRadioField();
        f1.setPlaceInPage(1);

        radiogroup.addKid(f1);

        RadioCheckField bt3=new RadioCheckField(writer, new Rectangle(100, 300, 120, 318), null, "v3");
        bt3.setCheckType(RadioCheckField.TYPE_CIRCLE);//圓型 radio
        bt3.setBackgroundColor(new GrayColor(0.8f));
        // bt2.setChecked(false);
        PdfFormField f3 = bt3.getRadioField();
        radiogroup.addKid(f3);

        RadioCheckField bt2=new RadioCheckField(writer, new Rectangle(100, 400, 120, 418), null, "v2");
        bt2.setCheckType(RadioCheckField.TYPE_CIRCLE);//圓型 radio
        bt2.setBackgroundColor(new GrayColor(0.8f));
        // bt2.setChecked(false);
        PdfFormField f2 = bt2.getRadioField();
        radiogroup.addKid(f2);

        pdfStamper.addAnnotation(radiogroup,1);
    }

button

使用比較少

 public static void creatPushbuttonField(PdfStamper pdfStamper) throws IOException, DocumentException {

     PdfWriter writer = pdfStamper.getWriter();
        //使表單不再可寫,也就是禁用表單了
         pdfStamper.setFormFlattening(true);
         pdfStamper.setFreeTextFlattening(true);

        PdfFormField form = PdfFormField.createPushButton(writer);

        PushbuttonField button = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1");
        button.setText(JAPANESE);
        button.setFontSize(0);
        // button.setImage(Image.getInstance("image.png"));
        button.setLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM);
        button.setBackgroundColor(new BaseColor(0, 255, 255));
        // button.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
        // button.setBorderColor( new BaseColor(255, 0, 0));
        // button.setBorderWidth(3);

        PdfFormField buttonFormField = button.getField();
        // buttonFormField.setAction(PdfAction.createSubmitForm("http://www.baidu.com", null, 0));
        // buttonFormField.setAction(PdfAction.createSubmitForm("http://www.baidu.com", null, 0));
        form.addKid(buttonFormField);

        pdfStamper.addAnnotation(form,1);
   }

表單域賦值

文字域賦值 text文字域名字,aa是展現在pdf文件上文字域中的內容
docData.put("text","aa")
radio賦值  text為radio組名字,aa為一組radio其中一個radio域名字,填寫後,在pdf即此radio勾選
docData.put("text","aa")
checkbox賦值 text為checkbox域名字,新增 “Yes” 或“Off”,表示勾選和不勾選
docData.put("text","Yes")

去除表單域

 public static void main(String[] args) {
        FileOutputStream out= null;
        PdfReader reader=null;
        PdfStamper pdfStamper=null;
        try {
            out = new FileOutputStream(new File(second));

            reader=new PdfReader(new FileInputStream(new File(save)));
            pdfStamper=new PdfStamper(reader,out);
            AcroFields s = pdfStamper.getAcroFields();


            Map<String, AcroFields.Item> acroFieldMap=s.getFields();
            Set<String> keySet = acroFieldMap.keySet();
            Object[] keySetStr = keySet.toArray();
            for (Object s1 : keySetStr) {
                s.removeField(s1.toString());
            }
            pdfStamper.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

PDF TO Image

public  static   void Pdf_Png(int pageNumber,String desk,String target )   {
        int pagen= pageNumber;
        File file = new File(DEST);

        PDFFile pdffile=null;
//      set up the PDF reading
        try{
            RandomAccessFile raf = new RandomAccessFile(file, "r");
            FileChannel channel = raf.getChannel();
            ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
            buf.clear();
            byte[] b = new byte[buf.capacity()];
            buf.get(b, 0, b.length);
            // FileOutputStream outputStream =new FileOutputStream("F:\\公司相關資料\\pdf\\test2.pdf");
            // outputStream.write(b);
            // outputStream.close();
            pdffile = new PDFFile(buf);
        } catch(Exception e){
            e.printStackTrace();
        }

        if(pagen<pdffile.getNumPages())
            return;
        //print出該pdf文件的頁數
        System.out.println(pdffile.getNumPages());

        //設定將第pagen也生成png圖片
        PDFPage page = pdffile.getPage(pagen);
//      create and configure a graphics object
        int width = (int)page.getBBox().getWidth();
        int height =(int)page.getBBox().getHeight();
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//      do the actual drawing
        PDFRenderer renderer = new PDFRenderer(page, g2,
                new Rectangle(0, 0, width, height), null, Color.RED);
        try{
            page.waitForFinish();
        }catch(Exception e){
            e.printStackTrace();
        }
        renderer.run();
        g2.dispose();

        try{
            ImageIO.write(img, "png", new File(target));
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }