绘制pdf表格 (一) 通过itext实现在pdf中绘制excel表格样式并且实现下载(支持中文字体)
目录
前言
将数据封装为excel表格样式,并且以PDF的形式的进行下载,可以使用Itextpdf
进行实现,当然也可以使用Aspose
通过流之间的转换进行实现,参考:
《SpringBoot实现Excel、Word转换为PDF》
《Aspose实现上传Excel、Word转换为PDF并进行下载》
1、引入POM
<dependencies> <dependency> <groupId>com.itextpdf</groupId> <artifactId>font-asian</artifactId> <version>7.2.1</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency> </dependencies>
2、查找字体
对于中文字体textpdf
不支持直接写入字体名称,所以需要进行手动指定ttc或者ttf类型的字体
,需要找到本机安装的字体位置,比如:C:\Windows\Fonts
,正确查找字体的步骤如下:
第一步: 进入C:\Windows\Fonts
:
进入到字体的安装目录,Windows默认为C:\Windows\Fonts
第二步: 查看字体信息
比如我们选择黑体
,那么黑体的simsun.ttc
3、编写工具类
3.1 字体配置
public class PdfUtils {/** * 设置字体默认值 * * @return * @throws DocumentException * @throws IOException */ private static BaseFont createBaseFont(String fontName) throws DocumentException, IOException { // 默认为宋体 if (fontName == null) { fontName = "simsun.ttc"; } String fontPre = fontName.substring(fontName.lastIndexOf(".") + 1); if (fontPre.equals("ttc")) { // ttc格式的字体需要加上后缀 fontName = fontName + ",0"; } String font = FONT_PATH + fontName; return BaseFont.createFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } /** * 设置字体 * * @return */ public static Font setFont() { return setFont(null, null, null, null); } public static Font setFont(Integer fontSize) { return setFont(null, fontSize, null, null); } public static Font setFont(Integer fontSize, BaseColor fontColor) { return setFont(null, fontSize, null, fontColor); } /** * @param fontName 字体名称 默认宋体 * @param fontSize 字体大小 默认12号 * @param fontStyle 字体样式 * @param fontColor 字体颜色 默认黑色 * @return */ public static Font setFont(String fontName, Integer fontSize, Integer fontStyle, BaseColor fontColor) { try { BaseFont baseFont = createBaseFont(fontName); Font font = new Font(baseFont); if (fontSize != null) { font.setSize(fontSize); } if (fontStyle != null) { font.setStyle(fontStyle); } if (fontColor != null) { font.setColor(fontColor); } return font; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("设置字体失败!"); } }}
3.2 创建pdf文档
public class PdfUtils { /** * 纸张大小 */ private static Rectangle RECTANGLE = PageSize.A4; /** * 创建pdf文档 * * @param response * @param fileName * @return */ public static Document createDocument(HttpServletResponse response, String fileName) { try { response.reset(); response.setHeader("Content-Type", "application/pdf-stream"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); } catch (Exception e) { e.printStackTrace(); } // 设置大小 RECTANGLE = PageSize.A4; return new Document(RECTANGLE, 50, 50, 80, 50); }}
3.3 创建段落标题
public class PdfUtils {/** * 设置表格内容 * * @param headFont * @param textFont * @param title * @param list * @return */ public static PdfPTable setTable(Font headFont, Font textFont, String[] title, List<User> list) { //四列 PdfPTable table = createTable(new float[]{120, 120, 120, 120}); for (String head : title) { table.addCell(createCell(head, headFont)); } for (User user : list) { table.addCell(createCell(user.getName(), textFont)); table.addCell(createCell(user.getGender(), textFont)); table.addCell(createCell(Integer.toString(user.getAgx()), textFont)); table.addCell(createCell(user.getAddress(), textFont)); } return table; } private static PdfPTable createTable(float[] widths) { PdfPTable table = new PdfPTable(widths); try { // 设置表格大小 table.setTotalWidth(RECTANGLE.getWidth() - 100); table.setLockedWidth(true); // 居中 table.setHorizontalAlignment(Element.ALIGN_CENTER); // 边框 table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } private 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; }}
3.4 设置表格
public class PdfUtils { /** * 绘制标题 * * @param font * @param titleName * @return */ public static Paragraph setParagraph(Font font, String titleName) { Paragraph paragraph = new Paragraph(titleName, font); //设置文字居中 paragraph.setAlignment(Element.ALIGN_CENTER); //行间距 paragraph.setLeading(5f); //设置段落上空白 paragraph.setSpacingBefore(-20f); //设置段落下空白 paragraph.setSpacingAfter(15f); return paragraph; }}
3.5 工具类完整代码
public class PdfUtils { /** * 字体存放的跟路径,默认为'C:\Windows\Fonts\' */ private static final String FONT_PATH = "C:\\Windows\\Fonts\\"; /** * 纸张大小 */ private static Rectangle RECTANGLE = PageSize.A4; /** * 设置字体默认值 * * @return * @throws DocumentException * @throws IOException */ private static BaseFont createBaseFont(String fontName) throws DocumentException, IOException { // 默认为宋体 if (fontName == null) { fontName = "simsun.ttc"; } String fontPre = fontName.substring(fontName.lastIndexOf(".") + 1); if (fontPre.equals("ttc")) { // ttc格式的字体需要加上后缀 fontName = fontName + ",0"; } String font = FONT_PATH + fontName; return BaseFont.createFont(font, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } /** * 设置字体 * * @return */ public static Font setFont() { return setFont(null, null, null, null); } public static Font setFont(Integer fontSize) { return setFont(null, fontSize, null, null); } public static Font setFont(Integer fontSize, BaseColor fontColor) { return setFont(null, fontSize, null, fontColor); } /** * @param fontName 字体名称 默认宋体 * @param fontSize 字体大小 默认12号 * @param fontStyle 字体样式 * @param fontColor 字体颜色 默认黑色 * @return */ public static Font setFont(String fontName, Integer fontSize, Integer fontStyle, BaseColor fontColor) { try { BaseFont baseFont = createBaseFont(fontName); Font font = new Font(baseFont); if (fontSize != null) { font.setSize(fontSize); } if (fontStyle != null) { font.setStyle(fontStyle); } if (fontColor != null) { font.setColor(fontColor); } return font; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("设置字体失败!"); } } /** * 创建pdf文档 * * @param response * @param fileName * @return */ public static Document createDocument(HttpServletResponse response, String fileName) { try { response.reset(); response.setHeader("Content-Type", "application/pdf-stream"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); } catch (Exception e) { e.printStackTrace(); } // 设置大小 RECTANGLE = PageSize.A4; return new Document(RECTANGLE, 50, 50, 80, 50); } /** * 绘制标题 * * @param font * @param titleName * @return */ public static Paragraph setParagraph(Font font, String titleName) { Paragraph paragraph = new Paragraph(titleName, font); //设置文字居中 paragraph.setAlignment(Element.ALIGN_CENTER); //行间距 paragraph.setLeading(5f); //设置段落上空白 paragraph.setSpacingBefore(-20f); //设置段落下空白 paragraph.setSpacingAfter(15f); return paragraph; } /** * 设置 * 表格内容 * * @param headFont * @param textFont * @param title * @param list * @return */ public static PdfPTable setTable(Font headFont, Font textFont, String[] title, List<User> list) { //四列 PdfPTable table = createTable(new float[]{120, 120, 120, 120}); for (String head : title) { table.addCell(createCell(head, headFont)); } for (User user : list) { table.addCell(createCell(user.getName(), textFont)); table.addCell(createCell(user.getGender(), textFont)); table.addCell(createCell(Integer.toString(user.getAgx()), textFont)); table.addCell(createCell(user.getAddress(), textFont)); } return table; } private static PdfPTable createTable(float[] widths) { PdfPTable table = new PdfPTable(widths); try { // 设置表格大小 table.setTotalWidth(RECTANGLE.getWidth() - 100); table.setLockedWidth(true); // 居中 table.setHorizontalAlignment(Element.ALIGN_CENTER); // 边框 table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } private 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; }}
4、pdf生成实现
代码:
@RestController@RequestMapping("/test")public class ExcelController {@GetMapping("/pdf") public void downloadPDF(HttpServletResponse response) { try (BufferedOutputStream os = new BufferedOutputStream(response.getOutputStream())) { // 1.设置输出的文件名称 String fileName = "考勤报表.pdf"; // 2.创建pdf文档,并且设置纸张大小为A4 Document document = PdfUtils.createDocument(response, fileName); PdfWriter.getInstance(document, os); // 3.打开文档 document.open(); // 4.设置标题 String titleName = "这 个 是 标 题"; // 设置字体样式:黑体 20号 加粗 红色 Font titleFont = PdfUtils.setFont("simhei.ttf", 20, Font.BOLD, BaseColor.RED); Paragraph paragraph = PdfUtils.setParagraph(titleFont, titleName); // 5.设置表格 // 定义列名 String[] title = {"姓名", "性别", "年龄", "地址"}; // 获取列表数据 // 设置表头字体样式:黑体 14号 加粗 黑色 // 设置正文字体样式:12号 Font headFont = PdfUtils.setFont("simhei.ttf", 12, Font.BOLD, BaseColor.BLACK); Font textFont = PdfUtils.setFont(12); // 模拟获取数据 List<User> dataList = getData(); PdfPTable table = PdfUtils.setTable(headFont, textFont, title, dataList); // 8.填充内容 document.add(paragraph); document.add(table); // 关闭资源 document.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 模拟从数据库获取数据 * * @return */ private List<User> getData() { List<User> list = new ArrayList<>(); for (int i = 0; i < 100; i++) { User user = new User(); user.setName("名称-" + i); user.setAddress("地址-" + i); user.setAgx(20); user.setGender("男"); list.add(user); } return list; }
效果: