使用itex生成pdf文件并下载总结

项目中需要根据数据库中查询到的数据生成pdf文件并下载

文章参考:https://blog.csdn.net/Agoni_3/article/details/123754089
最终效果图如下:
使用itex生成pdf文件并下载总结_第1张图片
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;
    }
}

开发中遇到的问题

  1. pdf字体问题
    在实际项目中使用的jar包版本是:
	<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之后就可以正常展示出来。

你可能感兴趣的:(导出,java)