Java 使用iText导出PDF

下面进入正题:

需求:根据List<对象>导出PDF。

想法:

  1. 因为之前导出过word,所以产生了一个想法就是先生成Word,然后整合为一个word,再转成PDF。这个想法进行到转PDF的时候,没有找到方法而放弃。
  2. 直接导出PDF,然后整和PDF,导出。(最后经过千辛万苦,九九八十一难,取得真经,并在Linux上测试成功)

废话不多说,下面是代码:

首先需要先引入Maven

 <!--pdf itext 的jar依赖  -->
      <dependency>
          <groupId>com.itextpdf</groupId>
          <artifactId>itextpdf</artifactId>
          <version>5.1.2</version>
      </dependency>
      <dependency>
          <groupId>com.itextpdf</groupId>
          <artifactId>itext-asian</artifactId>
          <version>5.1.1</version>
      </dependency>

 

然后是Controller

  private final static String PDF_TEMP_PATH = "template/pdf_template/pdfTemp.pdf";
    private final static String FONT_CN = "font/simsun.ttc";

@GetMapping(value = "/export/pdf" , produces = "application/pdf;charset=UTF-8")
    public void exportReplyDoc(HttpServletResponse response){
        List<OrderInfo> list = orderInfoService.list(Wrappers.<OrderInfo>query().lambda().last("limit 5"));
        List<PdfReader> readers = Lists.newArrayList();
        for (int i = 0; i < list.size(); i++) {
            OrderInfo info = list.get(i);
            //将info对象转换为String[]
            String[] str = modelConvertArray(info);
            PdfReader pdfReader =
        ExportPDF.fillTemplate(str, PDF_TEMP_PATH,FONT_CN);
            readers.add(pdfReader);
        }
        //合并导出的PDF
        ExportPDF.combinPdf(response,readers);
    }


public static String[] modelConvertArray (OrderInfo info) { 
    //该方法是将对象转换成 String[] ,自行转换即可;
}

 

最后重点util(记下来要考的!)

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import lombok.extern.log4j.Log4j;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

@Log4j
public class ExportPDF {

    /**
     * 使用模板生成PDF
     *
     * @param str          充填表格的数据
     * @param templatePath 模板路径
     * @param fontCn 中文包
     */
    public static PdfReader fillTemplate(String[] str, String templatePath ,String fontCn) {
        PdfReader reader ;
        ByteArrayOutputStream bos;
        PdfStamper stamper;
        try {
            reader = new PdfReader(templatePath);// 读取pdf模板
            bos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, bos);
            AcroFields form = stamper.getAcroFields();
            int i = 0;
            java.util.Iterator<String> it = form.getFields().keySet().iterator();
            //设置中文字体,如果不设置部分中文不显示。
            ExportPDF exportPDF = new ExportPDF();
            BaseFont bf = BaseFont.createFont(fontCn + ",1",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(bf);
            while (it.hasNext()) {
                String name = it.next().toString();
                form.setField(name, str[i++]);
            }
            stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
            stamper.close();
            Document doc = new Document();
            doc.open();
            PdfReader pdfReader = new PdfReader(bos.toByteArray());
            doc.close();
            return pdfReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 合并 pdf
     *
     * @param readers 所有要合并的PDF的集合
     * @param response
     * @throws Exception
     */
    public static void combinPdf( HttpServletResponse response, List<PdfReader> readers) {
        try {
            String targetFilename = "案件";
            response.setContentType("application/pdf;");
            response.setHeader("Content-disposition", "filename=" + new String(targetFilename.getBytes("GBK"), "ISO8859-1"));
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();
                    pageOfCurrentReaderPDF++;
                    PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
                }
                pageOfCurrentReaderPDF = 0;
            }
            document.close();
            writer.close();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
    }

}

碰到的BUG

1、关于导出文字部分不显示的问题,就需要加入字体了 simsun.ttc  ​这个字体可以在你电脑的 

C:\Windows\Fonts 目录下找到。然后复制出来,放到 resources 目录下就可以读取到文件了;

PDF模板也是相同的方法,放到resources 目录下即可;

2、为什么放到目录下还是不行呢?报空指针??

打包即可,代码运行时读取的是target目录下的文件。如果报错,打包试试吧。

3、打包之后报文件损坏的错误,需要在pom文件中如下设置  

<nonFilteredFileExtension>pdf</nonFilteredFileExtension>

<nonFilteredFileExtension>ttc</nonFilteredFileExtension>

<-- 如下 -->
<build>
    <plugins>
      <plugin>
        <!--默认:spring-boot热部署-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <nonFilteredFileExtensions>
                    <nonFilteredFileExtension>docx</nonFilteredFileExtension>
                    <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
                    <nonFilteredFileExtension>ttc</nonFilteredFileExtension>
                </nonFilteredFileExtensions>
            </configuration>
        </plugin>
    </plugins>
  </build>

​​

 

完结!谢谢大家

如果哪里有错误或者不足之处,欢迎大家指出,有什么问题可以一起交流一下。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值