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表单域可以任意添加自定义的东西,但是注意不要覆盖到下面模板里写死的东西(例如我这里的‘时间’)

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