java 生成pdf

1. 生成 pdf 文件

package com.leinovo.npi.datacenter.module.dashboard.helper;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.leinovo.npi.datacenter.report.core.model.ReportInstanceInfo;
import com.leinovo.npi.datacenter.report.core.model.ReportProfile;
import com.leinovo.npi.util.DateUtils;
import com.leinovo.platform.util.JwtUtil;
import org.apache.commons.collections.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

/**
 * @description: CustomerPdfHelper
 * @author: leiming5
 * @date: 2021/12/30 15:12
 */
public class CustomerPdfHelper extends DownloadHelper {

    public CustomerPdfHelper(ReportProfile reportProfile, ReportInstanceInfo recentlyReportInstanceInfo, HttpServletResponse response) {
        super(reportProfile, recentlyReportInstanceInfo, response);
    }

    /**
     * pdf 写入响应流
     * 1. 获取响应流
     * 2. 生成 pdf 文档
     * 3. 文档放入输出流
     * 4. pdf 文档 放入数据
     * 5. 关闭 pdf 文档
     *
     * @author leiming5
     */
    @Override
    public void download() {

        String dateString = DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS);
        response.setHeader("content-disposition", "attachment;filename=" + fileName + "_" + dateString + ".pdf");
        response.setContentType("application/octet-stream");

        try (OutputStream out = response.getOutputStream()) {
            // 1.新建document对象
            Document document = new Document(PageSize.A4);// 建立一个Document对象

            // 2.文档写入输出流
            PdfWriter.getInstance(document, out);

            // 3.打开文档
            document.open();

            // 4.向文档中添加内容
            appendDataToDocument(document);

            // 5.关闭文档
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 将 数据放入 文档
     *
     * @param document
     */
    public void appendDataToDocument(Document document) {

        addDocumentProperties(document);

        for (int i = 0; i < elementKeys.size(); i++) {
            String elementKey = elementKeys.get(i);
            appendDataToDocumentByKey(document, elementKey);
        }
    }

    private void addDocumentProperties(Document document) {
        document.addTitle(fileName);// 标题
        String username = JwtUtil.getUsername();
        document.addAuthor(username);// 作者
        document.addSubject(fileName);// 主题
        document.addKeywords(fileName);// 关键字
        document.addCreator(username);// 创建者
    }

    private void addGraph(Document document, String word) {
        try {
            document.add(new Paragraph(word));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过 报表元素 key 添加数据到 sheet
     *
     * @param document pdf 文档
     * @param excelKey 当前报表的 key
     * @return 下一个报表的起始行
     * @author leiming5
     */
    private void appendDataToDocumentByKey(Document document, String excelKey) {
        String elementTitle = getTitle(excelKey);
        List<String> elementHeader = getHeader(excelKey);
        if (CollectionUtils.isEmpty(elementHeader)) {
            return;
        }

        List<List<String>> elementData = getData(excelKey);

        DocumentHelper documentHelper = new DocumentHelper(elementTitle, elementHeader, elementData, document);
        documentHelper.appendElementToDocument(excelKey,elementTitle);
    }
}

2 pdf 中添加表格

package com.leinovo.npi.datacenter.module.dashboard.helper;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.leinovo.npi.datacenter.report.core.component.ProductPictureElement;
import com.leinovo.npi.datacenter.report.core.component.SupplyProfileElement;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.CategoryDataset;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @description: DocumentHelper
 * @author: leiming5
 * @date: 2021/12/30 18:31
 */
public class DocumentHelper {
    private String elementTitle;
    private List<String> elementHeader;
    private List<List<String>> elementData;
    private Document document;

    private static int maxWidth = 520;
    private static int titleSize = 6;
    private static int fontSize = 5;

    private static BaseColor whiteColor = UiHelper.getWhiteColor();
    private static BaseColor blackColor = UiHelper.getBlackColor();
    private static BaseColor greyColor = UiHelper.getGreyColor();
    private static BaseColor blueColor = UiHelper.getBlueColor();

    private static Font titlefont = FontFactory.getFont(FontFactory.TIMES_ROMAN, titleSize, Font.NORMAL, blackColor);
    private static Font headfont = FontFactory.getFont(FontFactory.TIMES_ROMAN, fontSize, Font.BOLD, whiteColor);
    private static Font bodyfont = FontFactory.getFont(FontFactory.TIMES_ROMAN, fontSize, Font.NORMAL, blackColor);


    public DocumentHelper(String elementTitle, List<String> elementHeader, List<List<String>> elementData, Document document) {
        this.elementTitle = elementTitle;
        this.elementHeader = elementHeader;
        this.elementData = elementData;
        this.document = document;
    }

    /**
     * 放入 表格、图表
     *
     * @return 下一个 报表元素的 开始index
     * @author leiming5
     */
    public void appendElementToDocument(String excelKey, String elementTitle) {

        appendTableToDocument();

        // 折线图+柱状图(同时出现;FG Demand Supply与 Material Demand Supply 动他选择)
        if (excelKey.contains(SupplyProfileElement.getECode())) {
            appendImageToDocument(excelKey, elementTitle);
            // 图片列表 Product Picture(翻页功能)
        } else if (excelKey.contains(ProductPictureElement.getECode())) {
            appendImageToDocument(excelKey, elementTitle);
        } else {
            appendImageToDocument(excelKey, elementTitle);
        }
    }

    /**
     * 插件无法直接生成 图表,只能通过前端生成 图标的图片,然后把连接放入 pdf
     *
     * @param excelKey element key
     * @author leiming5
     */
    private void appendImageToDocument(String excelKey, String elementTitle) {
        String chartName = excelKey + ".jpg";
        addGraph("");

        CategoryDataset dataset = ChartHelper.getDataset();
        JFreeChart chart = ChartHelper.getChart(dataset, elementTitle, "", "");
        ChartHelper.generateChart(chartName, chart);

        try {
            Image image = Image.getInstance(chartName);
            image.setAlignment(Image.ALIGN_CENTER);
            image.scalePercent(40);
            document.add(image);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        File file = new File(chartName);
        file.delete();
    }

    private void addGraph(String value) {
        try {
            document.add(new Paragraph(value));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * 1. 放入 标题
     * 2. 放入 excel 表头
     * 3. 放入 excel 数据
     * 4. 设置列的样式
     *
     * @return 下一个 报表元素的 开始index
     * @author leiming5
     */
    private void appendTableToDocument() {
        PdfPTable table = createTable(elementHeader.size());

        appendElementTitle(table);
        appendElementHeader(table);
        appendElementData(table);

        addTable(table);
    }

    private void addTable(PdfPTable table) {
        try {
            document.add(table);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    private void appendElementTitle(PdfPTable table) {
        table.addCell(createTitleCell(elementTitle, elementHeader.size()));
    }

    private void appendElementHeader(PdfPTable table) {
        for (String fieldName : elementHeader) {
            table.addCell(createHeadCell(fieldName));
        }
    }

    private void appendElementData(PdfPTable table) {

        for (List<String> row : elementData) {
            for (String cellData : row) {
                table.addCell(createBodyCell(cellData));
            }
        }
    }


    /**
     * 创建指定列宽、列数的表格
     *
     * @param headerSize 表头字段数量
     * @return 创建的表格
     * @author leiming5
     */
    public PdfPTable createTable(int headerSize) {

        float[] fieldNums = new float[headerSize];
        for (int i = 0; i < headerSize; i++) {
            fieldNums[i] = 30f;
        }

        PdfPTable table = new PdfPTable(fieldNums);

        try {
            table.setTotalWidth(maxWidth);
            table.setLockedWidth(true);
            table.setHorizontalAlignment(Element.ALIGN_CENTER);

            UiHelper.setDefaultCell(table.getDefaultCell());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return table;
    }


    /**
     * 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
     *
     * @param value
     * @param colspan
     * @return
     */
    public PdfPCell createTitleCell(String value, int colspan) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, titlefont));

        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setColspan(colspan);

        cell.setBorder(0);

        cell.setPadding(3.0f);
        cell.setPaddingTop(15.0f);
        cell.setPaddingBottom(8.0f);
        return cell;
    }

    /**
     * 创建单元格(指定字体)
     *
     * @param value
     * @return
     */
    public PdfPCell createBodyCell(String value) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, bodyfont));

        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBorderColor(greyColor);
        return cell;
    }

    public PdfPCell createHeadCell(String value) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, headfont));

        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBackgroundColor(blueColor);
        cell.setBorderColor(greyColor);
        return cell;
    }
}

3. pdf 放入chart

其实,是通过 jfree生成一张图片,再将图片放入pdf

package com.leinovo.npi.datacenter.module.dashboard.helper;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import java.awt.*;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 参考连接 : https://www.cnblogs.com/antlord/p/8325937.html
 * https://blog.csdn.net/u012373815/article/details/50327907
 *
 * @description: ChartHelper
 * @author: leiming5
 * @date: 2022/1/3 14:49
 */
public class ChartHelper {

    public static void generateChart(String chartName,JFreeChart chart ) {
        characterFix(chart);
        saveCharToFile(chart, chartName);
    }

    public static void saveCharToFile(JFreeChart chart, String fileName) {
        OutputStream out = null;
        int width = 1023;
        int height = 511;
        try {
            out = new BufferedOutputStream(new FileOutputStream(fileName));
            if (fileName.endsWith("png")) {
                ChartUtilities.writeChartAsPNG(out, chart, width, height);
            } else {
                ChartUtilities.writeChartAsJPEG(out, 1.0f, chart, width, height, null);
            }
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static CategoryDataset getDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.addValue(1310, "plan", "PEL Exit");
        dataset.addValue(720.68, "plan", "POR Exit");
        dataset.addValue(675.3, "plan", "TR");
        dataset.addValue(560, "plan", "EVT Start");
        dataset.addValue(680.88, "plan", "DVT1 Start");
        dataset.addValue(780, "plan", "DVT2 Start");
        dataset.addValue(13100, "actual", "PEL Exit");
        dataset.addValue(720.680, "actual", "POR Exit");
        dataset.addValue(6750.3, "actual", "TR");
        dataset.addValue(5600, "actual", "EVT Start");
        dataset.addValue(680.88, "actual", "DVT1 Start");
        dataset.addValue(7800, "actual", "DVT2 Start");

        return dataset;
    }

    public static JFreeChart getChart(CategoryDataset dataset, String title, String yAxisName, String xAxisName) {
        JFreeChart chart = ChartFactory.createLineChart(
//      JFreeChart chart = ChartFactory.createBarChart3D(
                title,// 图形名称
                xAxisName,// 分类名称,为横坐标名称
                yAxisName,// 值名称,为纵坐标名称
                dataset,// 数据集合
                PlotOrientation.VERTICAL,// 垂直显示
                true,// 是否显示图例
                false,// 是否使用工具提示
                false);// 是否使用url
        return chart;
    }

    public static void characterFix(JFreeChart chart) {
        // 配置字体
        Font xfont = new Font("宋体", Font.PLAIN, 12);// X轴
        Font yfont = new Font("宋体", Font.PLAIN, 12);// Y轴
        Font kfont = new Font("宋体", Font.PLAIN, 12);// 底部
        Font titleFont = new Font("宋体", Font.BOLD, 15); // 图片标题

        // 图形的绘制结构对象,对于饼图不适用
        CategoryPlot plot = chart.getCategoryPlot();

        // 图片标题
        chart.setTitle(new TextTitle(chart.getTitle().getText(), titleFont));

        // 底部
        LegendTitle legendTitle = chart.getLegend();
        if (legendTitle != null) {
            legendTitle.setItemFont(kfont);
        }

        // X 轴
        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setLabelFont(xfont);// 轴标题
        domainAxis.setTickLabelFont(xfont);// 轴数值
        domainAxis.setTickLabelPaint(Color.BLUE); // 字体颜色
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

        // Y 轴
        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setLabelFont(yfont);
        rangeAxis.setLabelPaint(Color.BLUE); // 字体颜色
        rangeAxis.setTickLabelFont(yfont);
    }

}

4. 字体等样式

package com.leinovo.npi.datacenter.module.dashboard.helper;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;

/**
 * @description: UiHelper
 * @author: leiming5
 * @date: 2021/12/31 11:20
 */
public final class UiHelper {


    public static void setDefaultCell(PdfPCell cell) {
        // 大小
        cell.setFixedHeight(14);

        // 边框
        cell.setBorder(1);
        cell.setBorderWidth(1);
        cell.setBorderColor(getBorderColor());

        // 字体,字体的样式、COLOR
        cell.addElement(getPhrase("second content"));

        // 背景
        cell.setBackgroundColor(getBlueColor());
    }

    /**
     * 短语
     *
     * @return
     */
    public static Phrase getPhrase(String content) {
        Phrase phrase = new Phrase();
        phrase.setFont(getDefaultFont());
        phrase.setLeading(12);// 行距
        phrase.add(content);

        return phrase;
    }

    /**
     * 设置字体
     * 有四种属性(字体,字号,字型,颜色)
     */
    public static Font getFont(int size, BaseColor color) {

        return FontFactory.getFont(FontFactory.TIMES_ROMAN, size, Font.NORMAL, color);
    }

    public static Font getDefaultFont() {

        return getFont(8, getBlackColor());
    }

    /**
     * 边框颜色
     */
    public static BaseColor getBorderColor() {
        return new BaseColor(231, 237, 243);
    }

    /**
     * 白色 表头字体,body背景
     */
    public static BaseColor getWhiteColor() {
        return new BaseColor(255, 255, 255);
    }

    /**
     * 蓝色 表头背景
     */
    public static BaseColor getBlueColor() {
        return new BaseColor(88, 135, 227);
    }

    /**
     * 黑色 body 字体颜色
     */
    public static BaseColor getBlackColor() {
        return new BaseColor(34, 34, 34);
    }

    /**
     * 灰色 body 背景颜色
     */
    public static BaseColor getGreyColor() {
        return new BaseColor(217, 226, 243);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值