目录

前言:       将 HTML 字符串(带图片)转换成 PDF 文件,可以使用 Flying Saucer 或者 iText 等第三方库。

(注)以下依赖是:

Gradle依赖坐标、用Maven的可以去官网查询、官网:https://mvnrepository.com/

存储PDF文件到本地:

存储PDF文件到服务器:

1)、iText第三方库依赖

2)、Flying Saucer第三方库依赖

一、以下是使用的 iText 库下、PDF转换

前言:
       将 HTML 字符串(带图片)转换成 PDF 文件,可以使用 Flying Saucer 或者 iText 等第三方库。

(注)以下依赖是:

Gradle依赖坐标、用Maven的可以去官网查询、官网:https://mvnrepository.com/

存储PDF文件到本地:

        iText库下的可以看:1.1和1.2代码实例

        Flying Saucer库下的可以看:2.1和2.2代码实例

存储PDF文件到服务器:

        iText库下的可以看:1.3代码实例

        本项目中就使用了iText库进行写的PDF文件到服务器,所以就没有写Flying Saucer库下的实例方法了

使用的是Mino服务器


1)、iText第三方库依赖

 implementation 'com.lowagie:itext:2.1.7'

implementation 'org.jsoup:jsoup:1.14.3'

implementation 'com.itextpdf:html2pdf:3.0.2'

implementation 'com.itextpdf:layout:7.1.18'

implementation 'com.itextpdf:kernel:7.1.16'

2)、Flying Saucer第三方库依赖

  implementation 'org.xhtmlrenderer:flying-saucer-pdf-itext5:9.1.22'

一、以下是使用的 iText 库下、PDF转换

1.1)、当前方法只适用于,全是英文数字的HTML的字符串时、我们直接上代码,简单易懂、

不过需要注意的是,你在应用第三方库是,导包一定要导入正确,否则会有一些方法是无法使用的。

注意:当前方法返回的PDF文件是存在本地的

    

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.font.FontProvider;

public static void main(String[] args) throws Exception {
        // 适合英文格式、HTML转PDF文件
        String html = "<html><head></head><body><h1>Hello World!</h1><p>This is an example of HTML to PDF conversion.</p></body></html>";
        String pdfPath = "D:\\outputPDF.pdf";

        // Convert HTML to PDF
        File file = new File(pdfPath);
        OutputStream outputStream = new FileOutputStream(file);
        PdfWriter writer = new PdfWriter(outputStream);
        PdfDocument pdfDocument = new PdfDocument(writer);

        ConverterProperties converterProperties = new ConverterProperties();
        HtmlConverter.convertToPdf(html, pdfDocument, converterProperties);

        // Close streams and document
        pdfDocument.close();
        outputStream.close();
    }

1.2)、当前方法适用于中文英文数字的HTIM字符串、也是直接上代码,简单易懂、相信大家都能看的懂得、对应的包一定要导入正确,否则会报错呦!

注:此方法也是保存在本地的文件

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.font.FontProvider;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;


public static void main(String[] args) {
        // 中文和英文的格式
        String html = "<html><head></head><body><h1>Hello World!</h1><p>This is an example of HTML to PDF conversion. 中国大好河山</p></body></html>";
        String pdfPath = "D:\\cumentPdf.pdf";
        File file = new File(pdfPath);
        try(OutputStream outputStream = new FileOutputStream(file)) {
            // 转换 HTML to PDF
            PdfWriter writer = new PdfWriter(outputStream);
            PdfDocument pdfDocument = new PdfDocument(writer);
            // 设置PDF大小
            pdfDocument.setDefaultPageSize(PageSize.A4);
            // 设置中文
            ConverterProperties converterProperties = new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider(true, true, true);
            converterProperties.setFontProvider(fontProvider);
            // html转换PDF
            HtmlConverter.convertToPdf(html, pdfDocument, converterProperties);
            // 关闭
            pdfDocument.close();
        } catch (Exception e){
            e.fillInStackTrace();
        }
    }

1.3)、此方法是上传到Mino服务器的一个思路、上传到服务器具体的方法,如果使用根据当前的业务逻辑进行书写、没有写过Mino服务器上传的,我这边可以给出一个简单的例子来,如果有不适当的地方,请自行修改只仅供参考!

private final MinoFileServiceImpl minoFileService;

    public TestService(MinoFileServiceImpl minoFileService) {
        this.minoFileService = minoFileService;
    }

    public void kk(){
        // 中文和英文的格式
        String html = "<html><head></head><body><h1>Hello World!</h1><p>This is an example of HTML to PDF conversion. 中国大好河山</p></body></html>";
        test2(html);
    }


    private void test2(String html){

        // 获取文件标题
        Element firstP = doc.selectFirst("p");
        String textContent = firstP != null ? firstP.text() : "";
        // 文件地址(文件名称)
        String pdfPath = textContent + ".pdf";

        try(ByteArrayOutputStream  outputStream = new ByteArrayOutputStream()) {
            // 转换 HTML to PDF
            PdfWriter writer = new PdfWriter(outputStream);
            PdfDocument pdfDocument = new PdfDocument(writer);
            // 设置PDF大小
            pdfDocument.setDefaultPageSize(PageSize.A4);
            // 设置中文
            ConverterProperties converterProperties = new ConverterProperties();
            // 服务器上使用的中午字体文件字体文件(该/simsun.ttf文件需要下载、可以放在resources目录下)
            InputStream inputStream = this.getClass().getResourceAsStream("/simsun.ttf");
            byte[] bytes = ByteToMultipartFileConverterUtil.inputStreamToByteArray(inputStream);
            FontProgram fontProgram = FontProgramFactory.createFont(bytes);
            FontProvider fontProvider = new DefaultFontProvider(true, true, true);
            fontProvider.addFont(fontProgram);
            converterProperties.setFontProvider(fontProvider);
            // html转换PDF
            HtmlConverter.convertToPdf(html, pdfDocument, converterProperties);
            // pdf文件流
            byte[] pdfBytes = outputStream.toByteArray();
            // byte转成  MultipartFile
            MultipartFile multipartFile = ByteToMultipartFileConverterUtil.convert(pdfBytes, pdfPath);
            // 文件上传(待上传的文件流、文件服务器的桶名称、路径)
            minoFileService.uploadFile(multipartFile,"test",pdfPath);
            // 关闭
            pdfDocument.close();
        } catch (Exception e){
            e.fillInStackTrace();
        }
    }

以上的方法就是简单的将字符串HTML转成PDF然后再上传到Mino服务器上,方法当中的MinoFileServiceImpl这个是文件上传的如果没有文件上传的代码可以看下1.4这个。

1.4)、Mino服务器文件上传

这个方法就是在 MinoFileServiceImpl 里面的,在我们文件上传中需要用到的上传的方法

@Override
    public boolean uploadFile(MultipartFile multipartFile,
                              String bucketName,
                              String filePath) {
        try {
            if (null == multipartFile || StringUtil.isEmpty(bucketName)) {
                logger.error("error message: 未传入有效的文件 或 bucket");
                return false;
            }
            logger.debug("debug message: 开始上传文件 <{}>", multipartFile);
            String fileName = StringUtil.isEmpty(filePath) ? multipartFile.getOriginalFilename() : filePath;
            // 默认上传至
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                    .contentType(multipartFile.getContentType()).build());
            return true;
        } catch (Exception e) {
            logger.error("error message: 文件 <{}> 上传失败,原因是:", multipartFile, e);
            return false;
        }
    }

1.5)、byte[]流转成MultipartFile流的方法

        这个是一个util工具类ByteToMultipartFileConverterUtil这个工具类,在文件上传的时候需要将流进行转换然后再上传的文件服务器上,提供此方法可以拿来直接使用

以上1.3中使用到的这个ByteToMultipartFileConverterUtil工具类的两个方法都在这里、可以参考以下代码

public class ByteToMultipartFileConverterUtil {

    private ByteToMultipartFileConverterUtil() {
    }

public static MultipartFile convert(byte[] pdfBytes, String fileName) {
        InputStream inputStream = new ByteArrayInputStream(pdfBytes);
        return new MultipartFile() {
            @NotNull
            @Override
            public String getName() {
                return "file";
            }

            @Override
            public String getOriginalFilename() {
                return StringUtil.isEmpty(fileName) ? "file.pdf" : fileName;
            }

            @Override
            public String getContentType() {
                return "application/pdf";
            }

            @Override
            public boolean isEmpty() {
                return pdfBytes.length == 0;
            }

            @Override
            public long getSize() {
                return pdfBytes.length;
            }

            @NotNull
            @Override
            public byte[] getBytes() {
                return pdfBytes;
            }

            @NotNull
            @Override
            public InputStream getInputStream() {
                return inputStream;
            }

            @Override
            public void transferTo(@NotNull java.io.File file) throws IllegalStateException {
                throw new UnsupportedOperationException("MultipartFiles must not be manually written to disk");
            }
        };
    }



public static byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
        // 使用 DataInputStream 包装 InputStream
        DataInputStream dis = new DataInputStream(inputStream);
        // 获取 InputStream 的数据长度
        int length = inputStream.available();
        // 创建 byte[] 数组,存储 InputStream 的数据
        byte[] bytes = new byte[length];
        // 读取 InputStream 中的数据并存储到 byte[] 数组中
        dis.readFully(bytes);
        return bytes;
    }
}

通过以上代码,我们将带有图片的 HTML 字符串转换成了 PDF 格式,并保存到了本地或服务器的 文件中。其中的中文部分使用了宋体字体,通过注册字体文件路径来加载字体。

当然,不同的 PDF 转换库的实现会有所不同,但是思路大致相似,都需要将 HTML 字符串通过某种方式转换为 PDF 格式。

更多推荐