使用 iText 导出pdf表格

iText 是一种生成PDF报表的Java组件,其maven依赖如下:

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.0.6</version>
</dependency>

老版本的jar包 itext-2.1.7.jar 依赖如下:

<dependency><groupId>com.lowagie</groupId>  <artifactId>itext</artifactId>  <version>2.1.7</version>
</dependency>

生成表格的关键类 com.itextpdf.text.pdf.PDFPTable

示例1:生成一张两行两列的表格。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException{PdfPTable table = new PdfPTable(2);//生成一个两列的表格PdfPCell cell;int size = 15;cell = new PdfPCell(new Phrase("one"));cell.setFixedHeight(size);//设置高度table.addCell(cell);cell = new PdfPCell(new Phrase("two"));cell.setFixedHeight(size);table.addCell(cell);cell = new PdfPCell(new Phrase("three"));cell.setFixedHeight(size);table.addCell(cell);cell = new PdfPCell(new Phrase("four"));cell.setFixedHeight(size);table.addCell(cell);return table;}public void createPDF(String filename) throws IOException {Document document = new Document(PageSize.A4);try {PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));document.addTitle("example of PDF");document.open();PdfPTable table = createTable(writer);document.add(table);} catch (FileNotFoundException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {document.close();}
}
效果如下图:

示例2:合并列。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException {PdfPTable table = new PdfPTable(2);//生成一个两列的表格...cell = new PdfPCell(new Phrase("five"));cell.setColspan(2);//设置所占列数cell.setFixedHeight(size*2);//设置高度cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中table.addCell(cell);return table;
}
效果如下图:

注意:每一行的长度要和初始化表格的长度相等,即要把整行给占满,否则后面的都不会打印出来,所以要用到 setColspan() 方法来合并列,使用 setRowspan() 方法合并行。

示例3:合并行。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException {PdfPTable table = new PdfPTable(2);//生成一个两列的表格...cell = new PdfPCell(new Phrase("five"));cell.setColspan(1);//设置所占列数cell.setRowspan(2);//合并行cell.setFixedHeight(size*2);//设置高度cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中table.addCell(cell);cell = new PdfPCell(new Phrase("six"));cell.setFixedHeight(size);table.addCell(cell);cell = new PdfPCell(new Phrase("seven"));cell.setFixedHeight(size);table.addCell(cell);return table;
}

效果如下:

事实上,实现行合并还有一种方法,就是table中再套一个table。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException {PdfPTable table = new PdfPTable(2);//生成一个两列的表格...cell = new PdfPCell(new Phrase("five"));cell.setColspan(1);//设置所占列数cell.setFixedHeight(size*2);//设置高度cell.setHorizontalAlignment(Element.ALIGN_CENTER);//设置水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//设置垂直居中table.addCell(cell);PdfPTable table2 = new PdfPTable(1);//新建一个tablecell = new PdfPCell(new Phrase("six"));cell.setFixedHeight(size);table2.addCell(cell);cell = new PdfPCell(new Phrase("seven"));cell.setFixedHeight(size);table2.addCell(cell);cell = new PdfPCell(table2);//将table放到cell中table.addCell(cell);//将cell放到外层的table中去return table;
}

示例4:在表格中加入单选框/复选框。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException {PdfPTable table = new PdfPTable(2);//生成一个两列的表格...Phrase phrase1 = new Phrase();Chunk chunk1 = new Chunk("         YES");Chunk chunk2 = new Chunk("          NO");phrase1.add(chunk1);phrase1.add(chunk2);cell = new PdfPCell(phrase1);cell.setColspan(2);table.addCell(cell);//增加两个单选框PdfFormField  radiogroup=PdfFormField.createRadioButton(writer, true);radiogroup.setFieldName("salesModel");Rectangle rect1 = new Rectangle(110, 722, 120, 712);Rectangle rect2 = new Rectangle(165, 722, 175, 712);RadioCheckField radio1 = new RadioCheckField(writer, rect1, null, "self-support" ) ;RadioCheckField radio2 = new RadioCheckField(writer, rect2, null, "cooprate") ;radio2.setChecked(true);PdfFormField radiofield1 = radio1.getRadioField();PdfFormField radiofield2 = radio2.getRadioField();radiogroup.addKid(radiofield1);radiogroup.addKid(radiofield2);writer.addAnnotation(radiogroup);return table;
}

效果如图:

这里需要自己去调节单选框的位置,即  Rectangle rect1 = new Rectangle(...) 里面的参数。

示例5:两种表格叠加,附件样式如下:

1)maven 依赖:
<!-- PDF工具类 -->
<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version>
</dependency>
<!-- PDF中文支持 -->
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>
<dependency><groupId>com.itextpdf.tool</groupId><artifactId>xmlworker</artifactId><version>5.5.13.1</version>
</dependency>
2)appication.properties
# 自定义存储或读取路径
#注:自定义路径时,默认的四个文件夹下中的“META-INF下的resoures文件夹”仍然有效,其他三个文件夹失效
#注:搜索文件时,自定义的文件夹的优先级要高于默认的四个文件夹
web.upload-path=C:/PDF/
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/static,classpath:/resources/,file:{web.upload-path}
springboot.mvc.static-path-pattern=/**
3)实现
@Value("${web.upload-path}")
private String uploadPath;public String generateOrgDocumentPdf() throws AppException, IOException, DocumentException {String newPDFPath = uploadPath  + "信息采集表.pdf";createTableFile(newPDFPath );return newPDFPath;
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import com.itextpdf.text.*;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itextpdf.text.pdf.PdfWriter;/*** 生成PDF文档*/
public void createTableFile(String newPDFPath) throws AppException, IOException, DocumentException {//新建Document对象,并打开Document document = new Document(PageSize.A4);try {//创建文件File file = new File(newPDFPath);PdfWriter writer = PdfWriter.getInstance(document,new FileOutputStream(file));//文档属性document.addTitle("Titl");document.addAuthor("Author");document.addSubject("Subject");document.addKeywords("Keywords");document.addCreator("Creator");//页边空白document.setMargins(60, 60, 80, 40);document.open();//添加内容//1、标题document.add(PdfFontUtils.getFont(1, "信息采集表"));//创建一个空行// document.add(Chunk.NEWLINE );//2、表格//2.1 设置表格列数:6PdfPTable table = new PdfPTable(6);//2.2 指定表格每一列宽度table.setWidths(new float[] {0.15f,0.15f,0.15f,0.15f,0.15f,0.25f});//2.3添加第一行内容//2.3.1添加第1列内容PdfPCell cell = new PdfPCell(PdfFontUtils.getFont(7, "字段1"));//设置第一行第一列背景颜色cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//2.3.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//2.3.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段2"));//设置背景颜色cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//2.3.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//2.3.5添加第5列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段3"));//设置背景颜色cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//2.3.6添加第6列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//2.4添加第2行,跨所有列cell = new PdfPCell(PdfFontUtils.getFont(7, "字段4"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(6);table.addCell(cell);//2.5添加第三行内容//2.5.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段5"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(3);table.addCell(cell);//2.5.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7,"字段6"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(2);table.addCell(cell);//2.5.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段7"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//2.6添加第四行内容//2.6.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7,  "内容"));//设置跨列数cell.setColspan(3);table.addCell(cell);//2.6.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7,  "内容"));//设置跨列数cell.setColspan(2);table.addCell(cell);//2.6.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7,  "内容"));table.addCell(cell);//2.7添加第五行内容//2.7.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段8"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(2);table.addCell(cell);//2.7.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段9"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(3);table.addCell(cell);//2.7.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7,"字段10"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//2.8添加第六行内容//2.8.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));//设置跨列数cell.setColspan(2);table.addCell(cell);//2.8.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));//设置跨列数cell.setColspan(3);table.addCell(cell);//2.8.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//2.9添加tabledocument.add(table);//3、新建一个表-8列table = new PdfPTable(8);//3.1添加第1行,跨所有列cell = new PdfPCell(PdfFontUtils.getFont(7, "字段11"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(8);table.addCell(cell);//3.2添加第2行内容//3.2.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段12"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.2.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段13"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.2.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段14"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.2.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段15"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.3添加第3行内容//3.3.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.3.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.3.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.3.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.4添加第4行,跨所有列cell = new PdfPCell(PdfFontUtils.getFont(7, "字段16"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(8);table.addCell(cell);//循环加入行为记录表格-length:需要循环添加的数据的多少for (int i = 1; i <= length; i++){//取数字的中文表达String num = this.getNumberChinese(Integer.toString(i));//3.5添加第5行(字段17),跨所有列-------我这里的字段17格式类似于:(一)行为一cell = new PdfPCell(PdfFontUtils.getFont(6, "(" + num + ")、行为" + num));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(8);table.addCell(cell);//3.6添加第6行//3.6.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段18"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.6.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段19"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.6.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段20"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.6.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段21"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));cell.setColspan(2);table.addCell(cell);//3.7添加第7行//3.7.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.7.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.7.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));cell.setColspan(2);table.addCell(cell);//3.7.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7,"内容"));cell.setColspan(2);table.addCell(cell);//3.8添加第8行,跨所有列cell = new PdfPCell(PdfFontUtils.getFont(6, "字段22"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));//设置跨列数cell.setColspan(8);table.addCell(cell);//3.10添加第9行//3.10.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段23"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.10.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.10.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段24"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.10.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.10.5添加第5列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段25"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.10.6添加第6列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.10.7添加第7列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段26"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.10.8添加第8列内容cell = new PdfPCell(PdfFontUtils.getFont(7,"内容"));table.addCell(cell);//3.11添加第10行//3.11.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段27"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.11.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.11.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段28"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.11.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.11.5添加第5列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段29"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.11.6添加第6列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.11.7添加第7列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段30"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.11.8添加第8列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.12添加第11行//3.12.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段31"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.12.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.12.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段32"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.12.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.12.5添加第5列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段33"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.12.6添加第6列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.12.7添加第7列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段34"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.12.8添加第8列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.13添加第12行//3.13.1添加第1列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段35"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.13.2添加第2列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.13.3添加第3列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段36"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.13.4添加第4列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.13.5添加第5列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段37"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.13.6添加第6列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);//3.13.7添加第7列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "字段38"));cell.setBackgroundColor(new BaseColor(0xC0,0xC0,0xC0));table.addCell(cell);//3.13.8添加第8列内容cell = new PdfPCell(PdfFontUtils.getFont(7, "内容"));table.addCell(cell);}//3.14添加tabledocument.add(table);} catch (Exception e) {e.printStackTrace();}//4、关闭documentdocument.close();
}/*** 将数字123转为中文格式一二三*/
private String getNumberChinese(String number) {String result = "";//存储数字与中文表示的键值对Map<String,String> map = new HashMap<String,String>();map.put("1","一");map.put("2","二");map.put("3","三");map.put("4","四");map.put("5","五");map.put("6","六");map.put("7","七");map.put("8","八");map.put("9","九");int len = number.length();if (len == 1) {result = map.get(number);} else if (len == 2) {result = map.get(number.substring(0,1)) + "十" + map.get(number.substring(1,2));}return result;
}
import java.io.IOException;
import java.net.URL;
import org.springframework.core.io.ClassPathResource;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;public class PdfFontUtils {/*** 文档排版*/public static Paragraph getFont(int type, String text) throws IOException{BaseFont songti = null;BaseFont heiti = null;BaseFont fangsong = null;URL url = new ClassPathResource("META-INF/resources/static/font/STZHONGS.TTF").getURL();String song = url.getPath();url = new ClassPathResource("META-INF/resources/static/font/SIMHEI.TTF").getURL();String hei = url.getPath();url = new ClassPathResource("META-INF/resources/static/font/STFANGSO.TTF").getURL();String fang = url.getPath();try {/*** 设置字体* * windows路径字体* FONT_TYPE=C:/Windows/fonts/simsun.ttc* linux路径字体 宋体 (如果没有这个字体文件,就将windows的字体传上去)* FONT_TYPE=/usr/share/fonts/win/simsun.ttc*/songti = BaseFont.createFont(song, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);heiti = BaseFont.createFont(hei, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);fangsong = BaseFont.createFont(fang, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);} catch (DocumentException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}Font font1 = new Font(songti);Font font2 = new Font(heiti);Font font3 = new Font(fangsong);if(1 == type){//1-标题font1.setSize(22f);} else if(2 == type){//2-标题一font2.setSize(16f);} else if(3 == type){//3-标题二font3.setSize(16f);} else if(4 == type){//4-标题三font3.setSize(16f);} else if(5 == type){//5-正文font3.setSize(10.5f);} else if(6 == type){//6-左对齐font3.setSize(10.5f);} else {font3.setSize(10.5f);//默认大小}//注: 字体必须和 文字一起newParagraph paragraph = null;if(1 == type){paragraph = new Paragraph(text, font1);paragraph.setAlignment(Paragraph.ALIGN_CENTER);//居中paragraph.setSpacingBefore(40f);//上间距paragraph.setSpacingAfter(30f);//下间距} else if(2 == type){//2-标题一paragraph = new Paragraph(text, font2);paragraph.setAlignment(Element.ALIGN_JUSTIFIED); //默认paragraph.setFirstLineIndent(40);paragraph.setSpacingBefore(20f);//上间距paragraph.setSpacingAfter(30f);//下间距} else if(3 == type){paragraph = new Paragraph(text, font3);paragraph.setFirstLineIndent(40);paragraph.setSpacingBefore(20f);//上间距paragraph.setSpacingAfter(1f);//下间距} else if(4 == type){//4-标题三paragraph = new Paragraph(text, font3);paragraph.setAlignment(Element.ALIGN_JUSTIFIED);paragraph.setFirstLineIndent(40);paragraph.setSpacingBefore(2f);//上间距paragraph.setSpacingAfter(2f);//下间距paragraph.setLeading(40f);//设置行间距} else if(5 == type){paragraph = new Paragraph(text, font3);paragraph.setAlignment(Element.ALIGN_JUSTIFIED); paragraph.setFirstLineIndent(40);//首行缩进paragraph.setSpacingBefore(1f);//上间距paragraph.setSpacingAfter(1f);//下间距} else if(6 == type){//左对齐paragraph = new Paragraph(text, font3);paragraph.setAlignment(Element.ALIGN_LEFT); paragraph.setSpacingBefore(1f);//上间距paragraph.setSpacingAfter(1f);//下间距}else if(7 == type){paragraph = new Paragraph(text, font3);paragraph.setAlignment(Element.ALIGN_CENTER);paragraph.setSpacingBefore(1f);//上间距paragraph.setSpacingAfter(1f);//下间距}return paragraph;}
}

示例6:在springboot中导出pdf文件。

@RequestMapping("printPdf")
public ModelAndView printPdf() throws Exception {Product product1 = new Product("产品一","cp01",120);Product product2 = new Product("产品一","cp01",120);Product product3 = new Product("产品一","cp01",120);List<Product> products = new ArrayList<>();products.add(product1);products.add(product2);products.add(product3);Map<String, Object> model = new HashMap<>();model.put("sheet", products);return new ModelAndView(new ViewPDF(), model);
}
public class ViewPDF extends AbstractPdfView {@Overrideprotected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer,HttpServletRequest request, HttpServletResponse response) throws Exception {String fileName = new Date().getTime() + "_quotation.pdf";response.setCharacterEncoding("UTF-8");response.setContentType("application/pdf");response.setHeader("Content-Disposition", "filename=" + new String(fileName.getBytes(), "iso8859-1"));List<Product> products = (List<Product>) model.get("sheet");PdfUtil pdfUtil = new PdfUtil();pdfUtil.createPDF(document, writer, products);}
}

注意

1、父类 AbstractPdfView 的 bulidPdfDocument 方法,其参数 document 的类型是 com.lowagie.text.Document ,意味着新版的 itextpdf-5.0.6.jar 不能使用,只能用老版本的(改名之前的)itext-2.1.7.jar。

2、如果不想要这种直接在浏览器中预览的效果,而是以附件形式直接下载文件,就修改 response.setHeader() 方法里的参数。

response.setHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes(), "iso8859-1"));
public class PdfUtil {public void createPDF(Document document,PdfWriter writer, List<Product> products) throws IOException {try {document.addTitle("sheet of product");document.addAuthor("scurry");document.addSubject("product sheet.");document.addKeywords("product.");document.open();PdfPTable table = createTable(writer,products);document.add(table);} catch (FileNotFoundException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();} finally {document.close();}}public static PdfPTable createTable(PdfWriter writer,List<Product> products) throws IOException, DocumentException { PdfPTable table = new PdfPTable(3);//生成一个三列的表格PdfPCell cell;int size = 20;Font font = new Font(BaseFont.createFont("C://Windows//Fonts//simfang.ttf", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED));   for(int i = 0;i<products.size();i++) {cell = new PdfPCell(new Phrase(products.get(i).getProductCode(),font));//产品编号cell.setFixedHeight(size);table.addCell(cell);cell = new PdfPCell(new Phrase(products.get(i).getProductName(),font));//产品名称cell.setFixedHeight(size);table.addCell(cell);cell = new PdfPCell(new Phrase(products.get(i).getPrice()+"",font));//产品价格cell.setFixedHeight(size);table.addCell(cell);}return table;}
}

如果项目要打包部署到linux服务器上,前两种的中文解决办法都不好使了,只能下载中文字体资源文件。然而这其中又有一个坑,打包后文件路径读取不到,需要以加载资源文件的形式读取文件。

BaseFont baseFont = BaseFont.createFont(new ClassPathResource("/simsun.ttf").getPath(), BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
效果如下图:

示例7:给浏览器输出pdf。

如果想给浏览器输出某些东西,可以流的方式,也可以字节的方式。
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfWriter.getInstance(document, out);
document.open();
document.add(table);
document.close();HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition","inline;filename=citiesreport.pdf");
ResponseEntity.ok().headers(headers).contentType(MediaType.APPLICATION_PDF).body(out.toByteArray());

示例8:给pdf文件添加水印(文字或图片)。

/*** 斜角排列、全屏多个重复的花式文字水印** @param input             需要加水印的PDF读取输入流* @param output            输出生成PDF的输出流* @param waterMarkString   水印字符* @param xAmout            x轴重复数量* @param yAmout            y轴重复数量* @param opacity           水印透明度* @param rotation          水印文字旋转角度,一般为45度角* @param waterMarkFontSize 水印字体大小* @param color             水印字体颜色*/
public static void stringWaterMark(InputStream input, OutputStream output, String waterMarkString, int xAmout, int yAmout, float opacity, float rotation, int waterMarkFontSize, BaseColor color) {try {PdfReader reader = new PdfReader(input);PdfStamper stamper = new PdfStamper(reader, output);// 添加中文字体BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);int total = reader.getNumberOfPages() + 1;PdfContentByte over;// 给每一页加水印for (int i = 1; i < total; i++) {Rectangle pageRect = stamper.getReader().getPageSizeWithRotation(i);// 计算水印每个单位步长X,Yfloat x = pageRect.getWidth() / xAmout;float y = pageRect.getHeight() / yAmout;over = stamper.getOverContent(i);PdfGState gs = new PdfGState();// 设置透明度为gs.setFillOpacity(opacity);over.setGState(gs);over.saveState();over.beginText();over.setColorFill(color);over.setFontAndSize(baseFont, waterMarkFontSize);for (int n = 0; n < xAmout + 1; n++) {for (int m = 0; m < yAmout + 1; m++) {over.showTextAligned(Element.ALIGN_CENTER, waterMarkString, x * n, y * m, rotation);}}over.endText();}stamper.close();} catch (Exception e) {new Exception("NetAnd PDF add Text Watermark error"+e.getMessage());}
}/*** 图片水印,整张页面平铺* @param input     需要加水印的PDF读取输入流* @param output    输出生成PDF的输出流* @param imageFile 水印图片路径*/
public static void imageWaterMark(InputStream input, OutputStream output, String imageFile, float opacity) {try {PdfReader reader = new PdfReader(input);PdfStamper stamper = new PdfStamper(reader, output);Rectangle pageRect = stamper.getReader().getPageSize(1);float w = pageRect.getWidth();float h = pageRect.getHeight();int total = reader.getNumberOfPages() + 1;Image image = Image.getInstance(imageFile);image.setAbsolutePosition(0, 0);// 坐标image.scaleAbsolute(w, h);PdfGState gs = new PdfGState();gs.setFillOpacity(opacity);// 设置透明度PdfContentByte over;// 给每一页加水印float x, y;Rectangle pagesize;for (int i = 1; i < total; i++) {pagesize = reader.getPageSizeWithRotation(i);x = (pagesize.getLeft() + pagesize.getRight()) / 2;y = (pagesize.getTop() + pagesize.getBottom()) / 2;over = stamper.getOverContent(i);over.setGState(gs);over.saveState();//没这个的话,图片透明度不起作用,必须在beginText之前,否则透明度不起作用,会被图片覆盖了内容而看不到文字了。over.beginText();// 添加水印图片over.addImage(image);}stamper.close();} catch (Exception e) {new Exception("NetAnd PDF add image Watermark error" + e.getMessage());}
}
效果如下图:

示例9:使用模板导出pdf。

使用模板的形式导出PDF,用 iText 对pdf模板进行动态数据的填充。

1、制作pdf模板
1.1、先在Word中编辑好对应的模板,如图,选择另存为,选择格式为pdf导出。

1.2、导出pdf格式后,使用PDF编辑器对其增加域面板,以及添加对应的文本域信息,我这边采用的PDF编辑器是 Gaaiho Doc(Gaaiho Doc)第一个月免费。选择添加文本域对表格进行添加,需要注意的是如果有单选框或多选框,另外需要设置默认导出值,这边与后台传送过来的数据相对应。根据导出值与后台对应的数据进行选中。

2、后端实现
2.1、在 pop.xml 中导入相关依赖

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

2.2、Service 层

@Override
public R exportPdf(HttpServletResponse response, Integer id){boolean flag=true;String path = "d:/";//获取数据Medicalrecords medicalrecords = medicalrecordsDao.findById(id);Doctor doctor = doctorDao.findById(medicalrecords.getDc_id());// 指定解析器System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");String filename="病历.pdf";response.setContentType("application/pdf");try {
//            int i=1/0;response.setHeader("Content-Disposition", "attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();return R.ok().put("flag",false);}OutputStream os = null;PdfStamper ps = null;PdfReader reader = null;try {os = response.getOutputStream();// 2 读入pdf表单(给予导出表单pdf的文件miing)reader = new PdfReader(path+ "/"+filename);// 3 根据表单生成一个新的pdfps = new PdfStamper(reader, os);// 4 获取pdf表单AcroFields form = ps.getAcroFields();// 5给表单添加中文字体 这里采用系统字体。不设置的话,中文可能无法显示
//            BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1",
//                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED);//这边设置pdf字体,可以更改字体的格式BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);form.addSubstitutionFont(bf);// 6查询数据(将数据赋给Map集合,key的值对应Pdf模板的值,value对应数据库中取出的)Map<String,Object> data = new HashMap<>();data.put("mr_uid",medicalrecords.getMr_uid());data.put("mr_name",medicalrecords.getMr_name());data.put("mr_gender",medicalrecords.getMr_gender());data.put("mr_birthday",medicalrecords.getMr_birthday());data.put("mr_address",medicalrecords.getMr_address());data.put("mr_telephone",medicalrecords.getMr_telephone());data.put("mr_illness",medicalrecords.getMr_illness());data.put("mr_diagnosis",medicalrecords.getMr_diagnosis());data.put("mr_drugs",medicalrecords.getMr_drugs());data.put("mr_doctor",doctor.getDc_name());data.put("mr_charge",medicalrecords.getMr_charge());data.put("mr_date",medicalrecords.getMr_date());// 7遍历data 给pdf表单表格赋值for (String key : data.keySet()) {form.setField(key, MapUtils.getString(data, key));}ps.setFormFlattening(true);flag=true;     } catch (Exception e) {flag=false;e.printStackTrace();return R.ok(e.getMessage()).put("flag",flag);} finally {try {ps.close();reader.close();os.close();} catch (Exception e) {e.printStackTrace();}}return null;
}

2.3、Controller 层

@GetMapping("/exportPdf/{mr_id}")
public R exportPdf(@PathVariable("mr_id") String id, HttpServletResponse response){return medicalrecordsService.exportPdf(response,Integer.parseInt(id));
}

解决中文字体的问题

1、使用windows系统自带的字体。

public static PdfPTable createTable(PdfWriter writer) throws DocumentException, IOException {Font font = new Font(BaseFont.createFont("C:/Windows/Fonts/SIMYOU.TTF",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED));PdfPTable table = new PdfPTable(2);//生成一个两列的表格int size = 20;PdfPCell cell = new PdfPCell(new Phrase("显示中文",font));cell.setFixedHeight(size);cell.setColspan(2);table.addCell(cell);return table;
}

2、使用 itext-asian.jar 中的中文字体。

Font font = new Font(BaseFont.createFont("STSongStd-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED));

在这里可能会报 Font 'STSongStd-Light' with 'UniGB-UCS2-H' is not recognized. 的错,把 itexitextpdf 包的版本从5.0.6改成5.4.3就解决了。

3、使用自己下载的资源字体。这种方法效果最好,能够应对各种系统、各种状况。

Font font = new Font(BaseFont.createFont("/simsun.ttf",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED));

SpringBoot 生成pdf文件(含报表)相关推荐

  1. springboot生成PDF文件返回给前台

    1制作好自己的pdf模版,我这里是通过wps把word转换成pdf文件 2下载Adobe Acrobat DC工具来制作pdf的模板 以上就是怎么制作pdf文件的模版 3引入maven 依赖 < ...

  2. SpringBoot+Vue+mybatis生成pdf文件(表头跟页码,适应上传linux服务器后的操作)

    SpringBoot+Vue+mybatis生成pdf文件(表头跟页码,适应上传linux服务器后的操作) 为什么使用后端去生成 说明 依赖 后端目录 控制器代码 模板代码 前端代碼 最終效果 为什么 ...

  3. springboot 基于.ftl模板生成pdf文件

    目录 Demo前置简述 生成pdf内容 项目结构 主要实现 api测试 完整代码地址 Demo前置简述 实现功能:用户个人信息测试数据加上ftl模板得到html字符串,然后根据html字符串生成pdf ...

  4. springboot根据模板生成pdf文件

    前言 最近碰到一个需求,给定一个word/pdf的模板,生成pdf文件,包含pdf文件之间的合并等操作.试了很多种方法(也可能是本人比较菜的原因),只有下面这个方法走通了,做下记录. 文件生成 1 准 ...

  5. java使用world模板动态生成PDF文件

    根据项目需求,需要用到一个功能,根据页面参数需要动态的生成一个world,并将world生成两份PDF文件,一份正式文件,一份临时的电子文件(带有二维码,扫描可以下载正式文件的电子版本).同时上传到文 ...

  6. 【PDF】使用 SpringBoot 导出 PDF 文件

    使用 iText 导出 pdf 表格 iText 是一种生成 PDF 报表的 Java 组件,先把 jar 包下下来,maven 依赖如下: <dependency><groupId ...

  7. Java生成PDF文件,java面试题,java初级笔试题

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 一. ...

  8. 使用itext将HTML 生成PDF文件

    1.使用itext将HTML模板生成PDF文件 HTML模板注意事项: 所有标签按语法正确闭合,否则会报错 table用border设置表格 如果下载到空白文件,看看整体XML的宽度 width使用% ...

  9. 生成PDF文件方案--学习中

    PDF文件是目前比较流行的电子文档格式,在办公自动化(OA)等软件的开发中,经常要用到该格式,但介绍如何制作PDF格式文件的资料非常少,在网上搜来搜去,都转贴的是同一段"暴力"破解 ...

最新文章

  1. 大有乾坤,售前机器人背后的 AI 技术
  2. 使用Python,将字符串的首字母变为大写,其余都变为小写
  3. python多久学会自学-零基础自学Python多久可以找工作?
  4. 【嵌入式开发】C语言 指针数组 多维数组
  5. android 广告栏效果,实现android广告栏效果
  6. jsp文件命名规范_代码规范整理
  7. 杂笔,Objective-C的认知
  8. 谷歌和ESRI眼中的Web Mercator
  9. SPOJ DISUBSTR Distinct Substrings 后缀数组
  10. 达梦数据库修改字段长度_Oracle、MySQL、达梦数据库新增修改删除字段
  11. ASTC纹理压缩格式详解
  12. Windows+iPad扩展屏幕-随航功能
  13. svg常用元素和属性
  14. Mac BERT 论文解读 Revisiting Pre-trained Models for Chinese Natural Language Processing
  15. java8新特性学习笔记(Lambda,stream(),filter(),collect(),map())
  16. QT5.14 安装与下载 教程
  17. 2022技术趋势预测,Python、Java占主导,Rust、Go增长迅速,元宇宙成为关注焦点
  18. 代驾行业开发APP需要注意哪些
  19. 如何姿势优美地招不到合适的程序员?——招不聘独孤九式
  20. 基于微信小程序的学生选课系统

热门文章

  1. m3u8下载,简化版,无解密
  2. ubuntu2204任务栏显示cpu 网速信息
  3. 记录一次FTP登录500 OOPS:cannot change directory解决方案
  4. Toshiba TC358743XBG HDMI接口转IC
  5. js的True、False判断
  6. 科技云报道:从“地摊经济”看云计算,产业寡头化趋势进一步加强
  7. 10种轻量级人脸检测算法大PK | 代码集合开源
  8. 销售管理岗位竞聘PPT模板
  9. win7虚拟机永恒之蓝漏洞复现
  10. Tomcat探秘(1):Tomcat是什么?