java itext后端生成pdf导出

java 复制代码
  public CustomApiResult<String> exportPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 防止日志记录获取session异常
        request.getSession();
        // 设置编码格式
        response.setContentType("application/pdf;charset=UTF-8");
        response.setCharacterEncoding("utf-8");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = URLEncoder.encode("成品检验检验单" + dateFormat.format(new Date()), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");
        // 表头id
        String id = request.getParameter("id");
        // 分录id
        String taskEntryId = request.getParameter("entryId");
// 数据
        DynamicObject dynamicObject = getPdfData(Long.valueOf(id), Long.valueOf(taskEntryId));
        download(response, dynamicObject);
        return CustomApiResult.success("成功");
    }

画pdf

java 复制代码
 public void download(HttpServletResponse response, DynamicObject data) throws IOException {
        // 定义全局的字体静态变量
        Font headfont;
        Font content;
        // 最大宽度
        try {
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            headfont = new Font(bfChinese, 14, Font.BOLD);
            content = new Font(bfChinese, 10, Font.NORMAL);

            BaseFont bf;
            Font font;
            //创建字体
            bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, 20, Font.BOLD, new Color(0, 0, 0));
            headfont = new Font(bf, 10, Font.BOLD, new Color(0, 0, 0));

            Document document = new Document(new RectangleReadOnly(842F, 595F));
            //设置页边距  60:左边距,60:右边距,72:上边距,72:下边距
            document.setMargins(60, 60, 72, 72);
            PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
            //添加页码
            writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            Paragraph paragraph = new Paragraph("成品检验 检验单", font);
            paragraph.setAlignment(1);
            //引用字体
            document.add(paragraph);

            // --------任务分录---设置表格的列宽和列数
            float[] widths = {25f, 25f, 25f, 25f, 25f, 25f};
            PdfPTable table = new PdfPTable(widths);
            table.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table.setWidthPercentage(100.0F);
            table.setHeaderRows(1);
            table.getDefaultCell().setHorizontalAlignment(1);
            PdfPCell cell = null;
            //第一行
            table.addCell(createCenteredCell("检验标准", 30, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_standard_name"), 0, null, content));

            table.addCell(createCenteredCell("检验日期", 0, null, headfont));
            table.addCell(createCenteredCell(String.valueOf(data.getDate("eo45_check_date")), 0, null, content));

            table.addCell(createCenteredCell("检验人员", 0, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_check_person"), 0, null, content));
            // 第二行
            table.addCell(createCenteredCell("生产厂家", 30, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_suppliers"), 0, null, content));

            table.addCell(createCenteredCell("物料名称", 0, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_material_names"), 0, null, content));

            table.addCell(createCenteredCell("物料规格", 0, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_specifications"), 0, null, content));
            //第三行
            table.addCell(createCenteredCell("物料批次", 30, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_material_batch"), 0, null, content));

            table.addCell(createCenteredCell("总数量", 0, null, headfont));
            table.addCell(createCenteredCell(data.getString("eo45_total"), 0, null, content));

            table.addCell(createCenteredCell("", 0, null, headfont));
            table.addCell(createCenteredCell("", 0, null, content));

            // --------检验详情---设置表格的列宽和列数
            float[] widths2 = {25f, 25f, 25f, 25f, 25f, 25f, 25f};
            PdfPTable table2 = new PdfPTable(widths2);
            table2.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table2.setWidthPercentage(100.0F);
            table2.setHeaderRows(1);
            table2.getDefaultCell().setHorizontalAlignment(1);
            // 第一行
            table2.addCell(createCenteredCell("序号", 30, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("检验项目", 0, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("标准要求", 0, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("检验方法及依据", 0, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("抽样数量", 0, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("实测结果", 0, new Color(204, 204, 204), headfont));
            table2.addCell(createCenteredCell("检验判定", 0, new Color(204, 204, 204), headfont));
            // 第二行开始循环数据
            DynamicObjectCollection item = data.getDynamicObjectCollection("eo45_zjy_task_item");
            Iterator var8 = item.iterator();
            int i = 0;
            while (var8.hasNext()) {
                i++;
                DynamicObject itemData = (DynamicObject) var8.next();
                PdfPCell cell1 = new PdfPCell(new Paragraph(String.valueOf(i), content));
                PdfPCell cell2 = new PdfPCell(new Paragraph(itemData.getString("eo45_project"), content));
                PdfPCell cell3 = new PdfPCell(new Paragraph(itemData.getString("eo45_standard_require"), content));
                PdfPCell cell4 = new PdfPCell(new Paragraph(itemData.getString("eo45_test_method"), content));
                PdfPCell cell5 = new PdfPCell(new Paragraph(itemData.getString("eo45_sample_qty"), content));
                JSONObject jsonObject = StringUtils.isNotEmpty(itemData.getString("eo45_actual_json"))
                        ? JSONObject.parseObject(itemData.getString("eo45_actual_json")) : new JSONObject();
                PdfPCell cell6 = new PdfPCell(new Paragraph("", content));
                String type = jsonObject.containsKey("type") ? jsonObject.getString("type") : "";
                // 根据json类型解析数据
                if ("number".equals(type)) {
                    cell6 = new PdfPCell(new Paragraph(jsonObject.containsKey("value") ? jsonObject.getString("value") : "", content));
                } else if ("select".equals(type)) {
                    JSONArray jsonArray = jsonObject.containsKey("option") ? JSONArray.parseArray(jsonObject.getString("option")) : null;
                    if (jsonArray != null) {
                        for (int j = 0; j < jsonArray.size(); j++) {
                            JSONObject jsonObject1 = jsonArray.getJSONObject(j);
                            if (jsonObject1.containsKey("selectStatus") && jsonObject1.getBoolean("selectStatus")) {
                                cell6 = new PdfPCell(new Paragraph(jsonObject.getString("eo45_value_mapping"), content));
                            }
                        }
                    }
                } else {
                    cell6 = new PdfPCell(new Paragraph(jsonObject.getString("eo45_actual_json"), content));
                }

                PdfPCell cell7 = new PdfPCell(new Paragraph(itemData.getString("eo45_item_decide"), content));

                //单元格对齐方式
                cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell1.setFixedHeight(20);
                //单元格垂直对齐方式
                cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell7.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);

                table2.addCell(cell1);
                table2.addCell(cell2);
                table2.addCell(cell3);
                table2.addCell(cell4);
                table2.addCell(cell5);
                table2.addCell(cell6);
                table2.addCell(cell7);
            }

            // ------综合判定----设置表格的列宽和列数
            // 设置表格的列宽和列数
            float[] widths3 = {25f, 75f};
            PdfPTable table3 = new PdfPTable(widths3);
            table3.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table3.setWidthPercentage(100.0F);
            table3.setHeaderRows(1);
            table3.getDefaultCell().setHorizontalAlignment(1);

            cell = new PdfPCell(new Paragraph("综合判定", headfont));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setFixedHeight(20);
            table3.addCell(cell);

            cell = new PdfPCell(new Paragraph(data.getString("eo45_decide"), content));
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table3.addCell(cell);

            for (int j = 0; j < 1; j++) {
                PdfPCell cell1 = new PdfPCell(new Paragraph("备注", headfont));
                String contentResult = "";
                // 富文本处理
                if (StringUtils.isNotBlank(data.getString("eo45_decide_result"))) {
                    org.jsoup.nodes.Document documentResult = Jsoup.parse(data.getString("eo45_decide_result"));
                    contentResult = documentResult.text();
                }
                PdfPCell cell2 = new PdfPCell(new Paragraph(contentResult, content));
                //设置居中
                cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell1.setFixedHeight(20);

                cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);

                table3.addCell(cell1);
                table3.addCell(cell2);
            }
            document.add(table);
            document.add(table2);
            document.add(table3);
            //关闭文档
            document.close();
        } catch (DocumentException e) {
            log.error("导出pdf失败DocumentException:{}", e);
        } catch (Exception e) {
            log.error("导出pdf失败Exception:{}", e);
        }
    }


  private PdfPCell createCenteredCell(String value, float fixedHeight, Color color, Font font) {
        PdfPCell cell = new PdfPCell(new Paragraph(value, font));
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        // 设置背景色
        if (color != null) {
            cell.setBackgroundColor(color);
        }
        // 设置单元格高度
        if (fixedHeight != 0) {
            cell.setFixedHeight(fixedHeight);
        }
        return cell;
    }

工具类

java 复制代码
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

import java.io.IOException;

/**
 * @Author xx
 * @Date 2023/12/15 10:05
 * @Description: 导出pdf添加页数
 * @Version 1.0
 */
public class PdfPageUtil extends PdfPageEventHelper {

    /**
     * 页眉
     */
    //public String header = "itext测试页眉";

    /**
     * 文档字体大小,页脚页眉最好和文本大小一致
     */
    public int presentFontSize = 9;

    /**
     * 文档页面大小,最好前面传入,否则默认为A4纸张
     */
    public Rectangle pageSize = PageSize.A4;

    // 模板
    public PdfTemplate total;

    // 基础字体对象
    public BaseFont bf = null;

    // 利用基础字体生成的字体对象,一般用于生成中文文字
    public Font fontDetail = null;

    /**
     *
     *  无参构造方法.
     *
     */
    public PdfPageUtil() {

    }

    /**
     *
     *  构造方法.
     *
     * @param
     *
     * @param presentFontSize
     *            数据体字体大小
     * @param pageSize
     *            页面文档大小,A4,A5,A6横转翻转等Rectangle对象
     */
    public PdfPageUtil( int presentFontSize, Rectangle pageSize) {
        this.presentFontSize = presentFontSize;
        this.pageSize = pageSize;
    }

    public void setPresentFontSize(int presentFontSize) {
        this.presentFontSize = presentFontSize;
    }

    /**
     *
     * 文档打开时创建模板
     */
    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        // 共 页 的矩形的长宽高
        total = writer.getDirectContent().createTemplate(50, 50);
    }

    /**
     *
     *关闭每页的时候,写入页眉,写入'第几页共'这几个字。
     */
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        this.addPage(writer, document);
    }

    //加分页
    public void addPage(PdfWriter writer, Document document){
        //设置分页页眉页脚字体
        try {
            if (bf == null) {
                bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
            }
            if (fontDetail == null) {
                fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 1.写入页眉
//        ColumnText.showTextAligned(writer.getDirectContent(),
//                Element.ALIGN_LEFT, new Phrase(header, fontDetail),
//                document.left(), document.top() + 20, 0);
        // 2.写入前半部分的 第 X页/共
        int pageS = writer.getPageNumber();
        //String foot1 = "第 " + pageS + " 页 /共";
        String foot1 = pageS  +"/";
        Phrase footer = new Phrase(foot1, fontDetail);

        // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
        float len = bf.getWidthPoint(foot1, presentFontSize);

        // 4.拿到当前的PdfContentByte
        PdfContentByte cb = writer.getDirectContent();

        // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F
        ColumnText
                .showTextAligned(
                        cb,
                        Element.ALIGN_CENTER,
                        footer,
                        (document.rightMargin() + document.right()
                                + document.leftMargin() - document.left() - len) / 2.0F ,
                        document.bottom() - 10, 0);
        cb.addTemplate(total, (document.rightMargin() + document.right()
                        + document.leftMargin() - document.left()) / 2.0F ,
                document.bottom() - 10); // 调节模版显示的位置

    }

//    //加水印
//    public void addWatermark(PdfWriter writer){
//        // 水印图片
//        Image image;
//        try {
//            image = Image.getInstance("./web/images/001.jpg");
//            PdfContentByte content = writer.getDirectContentUnder();
//            content.beginText();
//            // 开始写入水印
//            for(int k=0;k<5;k++){
//                for (int j = 0; j <4; j++) {
//                    image.setAbsolutePosition(150*j,170*k);
//                    content.addImage(image);
//                }
//            }
//            content.endText();
//        } catch (IOException | DocumentException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//    }

    /**
     *
     * 关闭文档时,替换模板,完成整个页眉页脚组件
     */
    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        // 关闭文档的时候,将模板替换成实际的 Y 值
        total.beginText();
        // 生成的模版的字体、颜色
        total.setFontAndSize(bf, presentFontSize);
        //页脚内容拼接  如  第1页/共2页
        //String foot2 = " " + (writer.getPageNumber()) + " 页";
        //页脚内容拼接  如  第1页/共2页
        String foot2 = String.valueOf(writer.getPageNumber() - 1);
        // 模版显示的内容
        total.showText(foot2);
        total.endText();
        total.closePath();
    }
}
相关推荐
南宫生4 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石12 分钟前
12/21java基础
java
李小白6620 分钟前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp33 分钟前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶1 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗1 小时前
常用类晨考day15
java
骇客野人1 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
yuanbenshidiaos2 小时前
c++---------数据类型
java·jvm·c++
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
Lojarro3 小时前
【Spring】Spring框架之-AOP
java·mysql·spring