java根据富文本内容生成pdf

先导入jar包

        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.8</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>


import cn.dazc.mediatecenter.utils.StrTool;
import cn.donganzichan.casefeign.feign.ICaseBatchFeign;
import cn.donganzichan.common.bean.web.ResponseResult;
import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.StandardCharsets;

import java.io.IOException;

/**
 * @author hyy
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PdfService {

    private final ICaseBatchFeign caseBatchFeign;

    @SneakyThrows
    public String contentToPdf(String content,String name) {
        // 创建一个文档
        Document document = new Document(PageSize.A4, 10, 10, 10, 10);
        String path = System.getProperty("user.dir") + "//" + name + ".pdf";
        try(OutputStream outputStream = new FileOutputStream(path)) {
            PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
            // 添加页眉页脚
            pdfWriter.setPageEvent(new PdfBuilder(new String[]{"", ""}));
            document.open();
            XMLWorkerHelper.getInstance().parseXHtml(pdfWriter, document,
                    new ByteArrayInputStream(("<html><body>"+content+"</body></html>").getBytes(StandardCharsets.UTF_8)),
                    StandardCharsets.UTF_8,new AsianFontProvider());
        } catch (Exception e) {
            log.error("生成pdf异常",e);
            return null;
        } finally {
            document.close();
        }
        // 将生成的pdf到oss
        try {
            File file = new File(path);
            InputStream is = new FileInputStream(file);
            ResponseResult<JSONObject> oss = caseBatchFeign.uploadOSS(new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), is));
            // 存完OSS,服务器不留存
            FileUtils.forceDelete(new File(path));
            String url = oss.getData().getString("path");
            if (StrTool.isEmpty(url))
                log.error("上传pdf失败");
            return url;
        } catch (Exception e) {
            log.error("上传pdf失败",e);
            // 存完OSS,服务器不留存
            FileUtils.forceDelete(new File(path));
            return null;
        }
    }
    
    static class AsianFontProvider extends XMLWorkerFontProvider {

         @Override
         public Font getFont(final String fontname, String encoding, float size, final int style) {
             String fntname = fontname;
             if (fntname == null) {
                 // 本地下载的字体文件,resources目录下
                 fntname = "simsun.ttf";
             }
             if (size == 0) {
                 size = 4;
             }
             return super.getFont(fntname, encoding, size, style);
         }
    }

    static class PdfBuilder extends PdfPageEventHelper {
    
        /**
         * 页眉
         */
        public String header = "";
    
        /**
         * 文档字体大小,页脚页眉最好和文本大小一致
         */
        public int presentFontSize = 12;
    
        /**
         * 文档页面大小,最好前面传入,否则默认为A4纸张
         */
        public Rectangle pageSize = PageSize.A4;
    
        // 模板
        public PdfTemplate total;

        public BaseFont bf = null;

        /**
         * 利用基础字体生成的字体对象,一般用于生成中文文字
         */
        public Font fontDetail = null;
    
    ///-------------------------------我是分界线---------------------------------------//
        /**
         * leftHeader
         */
        private final Phrase leftHeader;
        private final Phrase rightHeader;
    
        private static BaseFont baseFont;
        /**
         * 生成下划线空白占位符
         */
        private static String Blank;
        /**
         * 页眉字体
         */
        public static Font font;
        /**
         * 下划线字体
         */
        private static Phrase blankPhrase;
    
        public PdfBuilder(String[] header) {
            this.leftHeader = new Phrase(header[0], PdfBuilder.font);
            this.rightHeader = new Phrase(header[1], PdfBuilder.font);
        }
    
        static {
            try {
                // 中文字体依赖itext得itext-asian包
                baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 211; i++) {
                    sb.append("\u00a0");
                }
                Blank = sb.toString();
                font = new Font(PdfBuilder.baseFont, 12, Font.UNDEFINED);
                blankPhrase = new Phrase(PdfBuilder.Blank, new Font(PdfBuilder.baseFont, Font.DEFAULTSIZE, Font.UNDERLINE));
            } catch (DocumentException | IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 档打开时创建模板
         */
        @Override
        public void onOpenDocument(PdfWriter writer, Document document) {
            // 共 页 的矩形的长宽高
            total = writer.getDirectContent().createTemplate(50, 50);
        }

        @Override
        public void onEndPage(PdfWriter writer, Document document) {
            int yMargin = -20;
            float top = document.top(yMargin);
            float bottom = document.bottom(-65);
    
            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 | IOException e) {
                e.printStackTrace();
            }

            //生成下划线,使用空格占位
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_LEFT, PdfBuilder.blankPhrase,
                    document.right(-25), top, 180);
            //底部下划线
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_LEFT, PdfBuilder.blankPhrase,
                    document.right(-25), bottom, 180);
    
            //生成左侧页眉
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_LEFT, leftHeader,
                    document.left(), 38, 0);
            //生成右侧页眉
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_RIGHT, rightHeader,
                    document.right(), 0, 0);
    
            //生成页脚页数
            ColumnText.showTextAligned(writer.getDirectContent(),
                    Element.ALIGN_RIGHT, new Phrase("注:对本模板如有疑问,请及时与java开发组联系 ", new Font(PdfBuilder.baseFont, 8, Font.UNDEFINED)), document.right(), document.bottom(-45), 0);
    
            // 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 + " 页 /共";
            Phrase footer = new Phrase(foot1, fontDetail);
    
            // 3.计算前半部分的foot1的长度,后面好定位最后一部分的'Y页'这俩字的x轴坐标,字体长度也要计算进去 = len
            float len = baseFont.getWidthPoint(foot1, presentFontSize);
    
            // 4.拿到当前的PdfContentByte
            PdfContentByte cb = writer.getDirectContent();
    
            // 5.写入页脚 X=215 Y= -80
            ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, footer, (document.rightMargin()
                    + document.right() + document.leftMargin() - document.left() - len) / 2.0F + 215F, document.bottom() - 80, 0);
    
            // 6.写入页脚2的模板
            cb.addTemplate(total, (document.rightMargin() + document.right() + document.leftMargin()
                    // 调节模版显示的位置
                    - document.left()) / 2.0F + 215F, document.bottom() - 80);
        }
    
        /**
         * 关闭文档时,替换模板,完成整个页眉页脚组件
         */
        @Override
        public void onCloseDocument(PdfWriter writer, Document document) {
            // 关闭文档的时候,将模板替换成实际的 Y 值
            total.beginText();
            // 生成的模版的字体、颜色
            total.setFontAndSize(baseFont, presentFontSize);
            String foot2 = " " + (writer.getPageNumber()) + " 页";
            //模版显示的内容
            total.showText(foot2);
            total.endText();
            total.closePath();
        }
    }
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用Java的 iText 库来实现富文本生成PDF并进行下载。以下是一个简单的示例代码: ```java import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Font; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileOutputStream; import java.io.IOException; public class RichTextToPdf { public static void main(String[] args) { String richText = "<h1>标题</h1><p>这是一个示例富文本。</p><ul><li>列表项1</li><li>列表项2</li></ul>"; Document document = new Document(); try { PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf")); document.open(); // 设置字体 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font font = new Font(bfChinese, 12, Font.NORMAL); // 添加富文本内容PDF Paragraph paragraph = new Paragraph(); paragraph.setFont(font); paragraph.setLeading(20); paragraph.setMultipliedLeading(1); paragraph.setIndentationLeft(20); paragraph.setIndentationRight(20); paragraph.setFirstLineIndent(-20); paragraph.add(richText); document.add(paragraph); document.close(); writer.close(); System.out.println("PDF生成成功!"); } catch (DocumentException | IOException e) { e.printStackTrace(); } } } ``` 上述代码会生成一个名为 `output.pdf` 的PDF文件,其中包含了示例的富文本内容。你可以根据需要修改字体、样式、布局等参数来适应你的具体需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值