使用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表單域可以任意添加自定義的東西,但是注意不要覆蓋到下面模板裏寫死的東西(例如我這裏的‘時間’)