文章参考:https://blog.csdn.net/Agoni_3/article/details/123754089
最终效果图如下:
pom文件
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.RectangleReadOnly;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
/**
* 生成pdf文件工具类.
*
* @author
*
*/
public class PdfUtil {
// 表格高度
private static int high = 20;
// 表格宽度
private static int widthPercentage = 100;
private static Font keyfont;
private static Font textfont;
/**
* BASE_PATH.
*/
private static final String BASE_PATH;
// private static final String FONT_PATH;
// static {
// FONT_PATH = PdfUtil.class.getClassLoader().getResource("WEB-INF/font/MSYH.TTC").getPath();
// }
// 静态代码块
static {
try {
// 不同字体(这里定义为同一种字体:包含不同字号、不同style)
// BaseFont bfChinese = BaseFont.createFont(FONT_PATH + ",1",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
new Font(bfChinese, 16, java.awt.Font.BOLD);
new Font(bfChinese, 14, java.awt.Font.BOLD);
keyfont = new Font(bfChinese, 10, java.awt.Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
static {
final String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) {
BASE_PATH = "D:\\upload\\pdf\\";
} else {
BASE_PATH = "/data/upload/pdf/";
}
new File(BASE_PATH).mkdirs();
}
PdfUtil() {
}
public static void main(String[] args) {
try {
String dwmc = "单位名称xxxx";
// 表头文字
String[] titleName = new String[] { "名称", "税率", "备注", "金额" };
List<Map> data = new ArrayList<Map>();
Map<String,Object> e = new HashMap<>();
e.put("name","名称1");
e.put("tax_rate","0.08");
e.put("remark","备注1");
e.put("tax_fees","123.89");
data.add(e);
Map<String,Object> e1 = new HashMap<>();
e1.put("name","名称2");
e1.put("tax_rate","0.08");
e1.put("remark","备注2");
e1.put("tax_fees","123.89");
data.add(e1);
Map<String,Object> e2 = new HashMap<>();
e2.put("name","名称3");
e2.put("tax_rate","0.08");
e2.put("remark","备注3");
e2.put("tax_fees","123.89");
data.add(e2);
pdfOut(dwmc,titleName,data,"生成Pdf文件.pdf");
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 表格的样式
*
* @param content
* 内容
* @param font
* 字体对象
* @param high
* 表格高度
* @Param isAlignCenter 是否水平居中
* @Param isAlignMidde 是否垂直居中
* @return
*/
private static PdfPCell pdfTableStyle(String content, Font font, int high, boolean isAlignMidde,
int align) {
PdfPCell pdfPCell = new PdfPCell(new Phrase(content, font));
pdfPCell.setMinimumHeight(high);
pdfPCell.setUseAscender(true); // 设置可以居中
pdfPCell.setHorizontalAlignment(align); // 设置水平居中 0 左 1中 2 右
//pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); // 设置水平居中
if (isAlignMidde) {
pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // 设置垂直居中
}
return pdfPCell;
}
public static PdfPCell createCell(String value, Font font) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平居..)
*
* @param value
* @param font
* @param align
* @return
*/
public static PdfPCell createCell(String value, Font font, int align) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value, font));
cell.setPaddingTop(8.0f);
cell.setPaddingBottom(8.0f);
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并)
*
* @param value
* @param font
* @param align
* @param colspan
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPaddingTop(8.0f);
cell.setPaddingBottom(8.0f);
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
*
* @param value
* @param font
* @param align
* @param colspan
* @param boderFlag
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag,int height) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setMinimumHeight(height); //高度
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPadding(3.0f);
if (!boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(15.0f);
cell.setPaddingBottom(8.0f);
} else if (boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(0.0f);
cell.setPaddingBottom(15.0f);
}
return cell;
}
/**
* 检查是否存在文件夹并创建
*
* @param path
* @throws IOException
*/
public static File creatNewFile(String path) throws IOException {
File file = new File(path);
File fileParent = file.getParentFile();
if (!fileParent.exists()) {
fileParent.mkdirs();
}
file.createNewFile();
return file;
}
/**
* 创建单元格(指定字体、水平..、边框宽度:0表示无边框、内边距)
*
* @param value
* @param font
* @param align
* @param borderWidth
* @param paddingSize
* @param flag
* @return
*/
public PdfPCell createCell(String value, Font font, int align, float[] borderWidth, float[] paddingSize,
boolean flag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value, font));
cell.setBorderWidthLeft(borderWidth[0]);
cell.setBorderWidthRight(borderWidth[1]);
cell.setBorderWidthTop(borderWidth[2]);
cell.setBorderWidthBottom(borderWidth[3]);
cell.setPaddingTop(paddingSize[0]);
cell.setPaddingBottom(paddingSize[1]);
if (flag) {
cell.setColspan(2);
}
return cell;
}
/**
*
* @param dwmc 单位名称
* @param titleName 标题名称
* @param data 表格数据
* @throws IOException
* @throws DocumentException
*/
public static String pdfOut(String dwmc,String[] titleName,List<Map> data, String fileName) throws IOException, DocumentException {
String path = BASE_PATH + fileName;
// 判断路径中文件夹是否存在,不存在则自动创建,防止因为文件夹不存在而报错
creatNewFile(path);
// 新建一个pdf文档对象,前一个参数是纸张大小,后四个为边距
// 设置为A4横向
Document document = new Document(new RectangleReadOnly(842F, 595F));
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(path));
document.open();
// 添加标题
// 创建第一行表格
PdfPTable dwName = new PdfPTable(1);
dwName.setWidthPercentage(widthPercentage); // 设置标题长度占纸张比例
// 给表格赋值
// tableName.addCell(pdfTableStyle("测试pdf", size14font, 50, true, true));
dwName.addCell(createCell("单位名称:"+ dwmc, keyfont, Element.ALIGN_LEFT,1,false,20));
// 将表格添加到文档对象中
document.add(dwName);
// 创建第二行,并设置第二行中的表格数
PdfPTable table = new PdfPTable(titleName.length);
table.setWidthPercentage(widthPercentage);
// 该数组是每个表格的宽度
float[] floats = new float[titleName.length];
// 循环将表头数据添加到第二行表格中
for (int i = 0; i < titleName.length; i++) {
table.addCell(pdfTableStyle(titleName[i], keyfont, high, true, 1));
floats[i] = 0.1f;
}
// 设置表格的宽度
table.setTotalWidth(floats);
document.add(table);
// 将数据放入表格中
for (int i = 0; i < data.size(); i++) {
Map objects = data.get(i);
PdfPTable dataTable = new PdfPTable(titleName.length);
dataTable.setWidthPercentage(widthPercentage);
dataTable.setTotalWidth(floats);
// 将数组中的数据按照顺序添加
dataTable.addCell(pdfTableStyle(objects.get("name") == null ? "" :String.valueOf(objects.get("name")), textfont, high, true, 0));
dataTable.addCell(pdfTableStyle(objects.get("tax_rate") == null ? "" :String.valueOf(objects.get("tax_rate")), textfont, high, true, 1));
dataTable.addCell(pdfTableStyle(objects.get("remark") == null ? "" :String.valueOf(objects.get("remark")), textfont, high, true, 0));
dataTable.addCell(pdfTableStyle(new BigDecimal(objects.get("tax_fees").toString()).toPlainString(), textfont, high, true, 2));
document.add(dataTable);
}
document.close();
writer.close();
return path;
}
}
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.8</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
使用上面的字体生成的文件是没有字的,一片空白,使用了itext自带的字体但是不能展示中文,所以后来在项目中添加了微软雅黑的字体,具体代码如下:
private static final String FONT_PATH;
static {
FONT_PATH = PdfUtil.class.getClassLoader().getResource("xxx/MSYH.TTC").getPath();
}
// 静态代码块
static {
try {
// 不同字体(这里定义为同一种字体:包含不同字号、不同style)
BaseFont bfChinese = BaseFont.createFont(FONT_PATH + ",1",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
// ,1 必须添加,否则还是空白
new Font(bfChinese, 16, java.awt.Font.BOLD);
new Font(bfChinese, 14, java.awt.Font.BOLD);
keyfont = new Font(bfChinese, 10, java.awt.Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
2.需要将pdf文件传输给别人,开始使用的post,那边一直接受不到文件流,后来改为get就可以
3.切换到测试环境之后,下载还是有问题,最后在linux装了字体,把微软雅黑的字体放入字体目录下,代码里面兼容windows和linux之后就可以正常展示出来。