Bug:pdfbox缺少字体、字符串过长问题、Base64转换工具类

常见Base64问题及Base64转换工具类

1 Base64常见问题

1.1 base64字符串过长

Idea报:字符串过长

将编译器改为eclipse即可
在这里插入图片描述

注意:使用Eclipse的compiler无法再使用lombok插件,会报错

2 Base64转换工具类

2.1 Base64pdf转为Base64png【转换问题】

将base64编码后的pdf转为base64编码后的png

/**
 * base64 pdf转换为 base64的png格式
 * @param base64Pdf
 * @param format [png]
 * @return
 * @throws IOException
 */
public static String base64PDF2PNG(String base64Pdf, String format) throws IOException {
    
    
    String resultBase64 = "";
    //这个base64是pdf的base64
    if (StringUtils.isEmpty(base64Pdf)) {
    
    
        return resultBase64;
    }
    PDDocument pdDocument = null;
    Base64Decoder decoder = new Base64Decoder();
    try {
    
    
        // Base64解码
        byte[] pdf_bytes = decoder.decode(base64Pdf);
        PDDocument doc = Loader.loadPDF(pdf_bytes);
        int size = doc.getNumberOfPages();
        /*图像合并使用的参数*/
        //定义宽度
        int width = 0;
        // 保存一张图片中的RGB数据
        int[] singleImgRGB;
        // 定义高度,后面用于叠加
        int shiftHeight = 0;
        //保存每张图片的像素值
        BufferedImage imageResult = null;
        // 利用PdfBox生成图像
        pdDocument = doc;
        PDFRenderer renderer = new PDFRenderer(pdDocument);
        /*根据总页数, 按照50页生成一张长图片的逻辑, 进行拆分*/
        // 每50页转成1张图片
        int pageLength = size; //有多少转多少
        // 总计循环的次数
        int totalCount = pdDocument.getNumberOfPages() / pageLength + 1;
        for (int m = 0; m < totalCount; m++) {
    
    
            for (int i = 0; i < pageLength; i++) {
    
    
                int pageIndex = i + (m * pageLength);
                if (pageIndex == pdDocument.getNumberOfPages()) {
    
    
                    break;
                }
                // 96为图片的dpi,dpi越大,则图片越清晰,图片越大,转换耗费的时间也越多
                BufferedImage image = renderer.renderImageWithDPI(pageIndex, 150, ImageType.RGB);
                int imageHeight = image.getHeight();
                int imageWidth = image.getWidth();
                if (i == 0) {
    
    
                    //计算高度和偏移量
                    //使用第一张图片宽度;
                    width = imageWidth;
                    // 保存每页图片的像素值
                    // 加个判断:如果m次循环后所剩的图片总数小于pageLength,则图片高度按剩余的张数绘制,否则会出现长图片下面全是黑色的情况
                    if ((pdDocument.getNumberOfPages() - m * pageLength) < pageLength) {
    
    
                        imageResult = new BufferedImage(width, imageHeight * (pdDocument.getNumberOfPages() - m * pageLength), BufferedImage.TYPE_INT_RGB);
                    } else {
    
    
                        imageResult = new BufferedImage(width, imageHeight * pageLength, BufferedImage.TYPE_INT_RGB);
                    }
                } else {
    
    
                    // 将高度不断累加
                    shiftHeight += imageHeight;
                }
                singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width);
                imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width);
            }
            // 这个很重要,下面会有说明
            shiftHeight = 0;
        }
        pdDocument.close();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
        ImageIO.write(imageResult, format, baos);//写入流中
        byte[] jpg_Bytes = baos.toByteArray();//转换成字节
        BASE64Encoder encoder = new BASE64Encoder();
        resultBase64 = encoder.encodeBuffer(jpg_Bytes).trim();//转换成base64串
        resultBase64 = resultBase64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
        baos.close();
        doc.close();
        return resultBase64;
    } catch (IOException e) {
    
    
        e.printStackTrace();
    } finally {
    
    
        if (pdDocument != null) {
    
    
            pdDocument.close();
        }
    }
    return resultBase64;
}

对应pom依赖:

 <dependency>
     <groupId>org.apache.pdfbox</groupId>
     <artifactId>pdfbox-tools</artifactId>
     <version>3.0.0-RC1</version>
 </dependency>

Bug:如果遇到base64编码之后发现生成的png图片中缺少对应的中文字体,则可能是因为对应服务器上没有相应的字体导致。

① 可以下载pdbox的源码,然后修改里面的FontMapperImpl,编译打包之后重新替换为新的类。
在这里插入图片描述
直接在substitutes中增加映射字体对应的映射字体即可,如:STSong-Light->STFangsong。

然后使用maven编译打包,并且使用编译后的jar包
按照说明 在.\pdfbox 文件夹下 运行 mvn clean install

  • 但是会运行 test,我这里会报错 所以我关闭了测试 mvn clean install -DskipTests

②或者可以直接在对应的服务器上下载对应的字体。

# linux上下载对应字体【如:宋体】
#新建目录newFont以存放新字体
mkdir /usr/share/fonts/chinese/
#上传或者拷贝当前目录下的字体到/usr/share/fonts/chinese中
# 建立字体缓存
cd /usr/share/fonts/chinese/
mkfontscale; mkfontdir; fc-cache -fv

注意事项:更新字体缓存重启java应用依旧失败报错,删除/root目录下的.pdfbox.cache文件,重启应用后OK(此问题PDFBOX2.0.4版本会出现)

猜你喜欢

转载自blog.csdn.net/weixin_45565886/article/details/129685116