Itext導出pdf教程

使用itext生成pdf文件,通過模版和程序相結合的方式控制文件格式。文件中固定的部分可以用模版控制格式 省時又省力,需要動態變化的部分通過程序控制其格式 靈活可控。

1、先用word做出固定模板並且另存爲pdf格式

2、用Adobe Acrobat創建表單域 支持在程序裏動態賦值。(注意下面的額else域就是我們爲程序控制文件留的一個窗口)

到此位置模板就算是完成了,直接在項目裏找個目錄放進去就可以。

3、引jar包 pom文件如下

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.12</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

4、java代碼如下

package com.example.demo;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

@Controller
@RequestMapping(value="/itextTest")	
public class ItextTestController {
	
	@RequestMapping(value="/text")	
	public void test(HttpServletRequest request, HttpServletResponse response) {
		
        BufferedOutputStream out = null;

        //獲取類路徑
        String path = this.getClass().getClassLoader().getResource("").getPath();
        System.out.println(path);
        
        try {
        	
        	//模板文件
        	File templateFile = new File(path + "demo.pdf");
        	InputStream input = new FileInputStream(templateFile);
            PdfReader reader = new PdfReader(input);
            PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(path + "result.pdf"));
            
            //向表單域裏塞數據
            AcroFields form = stamper.getAcroFields();
            form.setField("title", "pdf打印測試");
            form.setField("name", "kaka");
            form.setField("phone", "123456");
            form.setField("addr", "beijing");
            form.setField("time", "2019-10-29");
            
            //插入自定義表格  利用模板裏的else表單域確定位置,表格樣式和數據用代碼控制
            AcroFields s = stamper.getAcroFields();
            insertElse(stamper, s);
            
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            
            //導出操作
            File file = new File(path + "result.pdf");
            long fileSize = file.length();
            FileInputStream fi = new FileInputStream(file);
            byte[] buffer = new byte[(int) fileSize];
            int offset = 0;
            int numRead = 0;
            while (offset < buffer.length
                && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
                offset += numRead;
            }
            fi.close();
            if (buffer.length != 0) {
            	response.reset();
                String name = URLEncoder.encode("測試.pdf", "UTF-8");
                response.setCharacterEncoding("utf-8");
                response.setContentType("multipart/octet-stream");
                response.setHeader("Content-Disposition", "attachment;filename=" + name);
                response.setContentLength(buffer.length);
                out = new BufferedOutputStream(response.getOutputStream());
                out.write(buffer);
                out.flush();
            }
        	
        }catch(Exception e) {
        	e.printStackTrace();
        }finally {
            if (out != null) {
            	try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
            }
        }

		
	}
	
	/**
	 * 向表單域插入自定義表格
	 * @param ps
	 * @param s
	 */
	public void insertElse(PdfStamper ps, AcroFields s) {
		
		List<AcroFields.FieldPosition> list = s.getFieldPositions("else");
        Rectangle rect = list.get(0).position;

        //設置表格爲兩列
        PdfPTable table = new PdfPTable(2);
        
        PdfContentByte cb = ps.getOverContent(1);

        float tatalWidth = rect.getRight() - rect.getLeft() - 1;
        table.setTotalWidth(tatalWidth);
        
        for(int i=0;i<6;i++) {
            PdfPCell cell = new PdfPCell(new Phrase(CreateChunk("表格數據"+i)));
            cell.setFixedHeight(rect.getTop() - rect.getBottom() - 1);
            cell.setBorderWidth(1);
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setLeading(0, (float) 1.1);
            table.addCell(cell);
        }
        table.writeSelectedRows(0, -1, rect.getLeft(), rect.getTop(), cb);
		
	}
	
	/**
	 * 設置字體
	 * @param param
	 * @return
	 */
    public Chunk CreateChunk(String param) {
        BaseFont bfChinese;
        Chunk chunk = null;
        try {
            bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            Font fontChinese = new Font(bfChinese, 10 * 4 / 3);
            chunk = new Chunk(param, fontChinese);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return chunk;
    }

}

我這裏爲了方便就沒寫頁面,瀏覽器通過url訪問該方法就可以直接下載pdf文件

通過下方預留的else表單域可以任意添加自定義的東西,但是注意不要覆蓋到下面模板裏寫死的東西(例如我這裏的‘時間’)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章