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版本会出现)

3 高德、百度、腾讯坐标互转

public class LngLonUtil {
	
	public static double pi = 3.1415926535897932384626;  
    public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
    public static double a = 6378245.0;  
    public static double ee = 0.00669342162296594323;  
  
    public static double transformLat(double x, double y) {  
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));  
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;  
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;  
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;  
        return ret;  
    }  
  
    public static double transformLon(double x, double y) {  
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));  
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;  
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;  
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;  
        return ret;  
    }  
    public static double[] transform(double lat, double lon) {  
        if (outOfChina(lat, lon)) {  
            return new double[]{lat,lon};  
        }  
        double dLat = transformLat(lon - 105.0, lat - 35.0);  
        double dLon = transformLon(lon - 105.0, lat - 35.0);  
        double radLat = lat / 180.0 * pi;  
        double magic = Math.sin(radLat);  
        magic = 1 - ee * magic * magic;  
        double sqrtMagic = Math.sqrt(magic);  
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);  
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);  
        double mgLat = lat + dLat;  
        double mgLon = lon + dLon;  
        return new double[]{mgLat,mgLon};  
    }  
/** 
     * 判断是否在中国
     * @param lat 
     * @param lon 
     * @return 
     */  
    public static boolean outOfChina(double lat, double lon) {  
        if (lon < 72.004 || lon > 137.8347)  
            return true;  
        if (lat < 0.8293 || lat > 55.8271)  
            return true;  
        return false;  
    }  
    /** 
     * 84 ==》 高德
     * @param lat 
     * @param lon 
     * @return 
     */  
    public static double[] gps84_To_Gcj02(double lat, double lon) {  
        if (outOfChina(lat, lon)) {  
            return new double[]{lat,lon};  
        }  
        double dLat = transformLat(lon - 105.0, lat - 35.0);  
        double dLon = transformLon(lon - 105.0, lat - 35.0);  
        double radLat = lat / 180.0 * pi;  
        double magic = Math.sin(radLat);  
        magic = 1 - ee * magic * magic;  
        double sqrtMagic = Math.sqrt(magic);  
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);  
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);  
        double mgLat = lat + dLat;  
        double mgLon = lon + dLon;  
        return new double[]{mgLat, mgLon};  
    }  
  
    /** 
     * 高德 ==》 84 
     * @param lon * @param lat * @return 
     * */  
    public static double[] gcj02_To_Gps84(double lat, double lon) {  
        double[] gps = transform(lat, lon);  
        double lontitude = lon * 2 - gps[1];  
        double latitude = lat * 2 - gps[0];  
        return new double[]{latitude, lontitude};  
    }  
    /** 
     * 高德 == 》 百度
     * @param lat 
     * @param lon 
     */  
    public static double[] gcj02_To_Bd09(double lat, double lon) {  
        double x = lon, y = lat;  
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);  
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);  
        double tempLon = z * Math.cos(theta) + 0.0065;  
        double tempLat = z * Math.sin(theta) + 0.006;  
        double[] gps = {tempLat,tempLon};  
        return gps;  
    }  
  
    /** 
     * 百度 == 》 高德
     * @param lat 
     * @param lon 
     */  
    public static double[] bd09_To_Gcj02(double lat, double lon) {  
        double x = lon - 0.0065, y = lat - 0.006;  
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);  
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);  
        double tempLon = z * Math.cos(theta);  
        double tempLat = z * Math.sin(theta);  
        double[] gps = {tempLat,tempLon};  
        return gps;  
    }  
  
    /**
     * 84 == 》 百度 
     * @param lat 
     * @param lon 
     * @return 
     */  
    public static double[] gps84_To_bd09(double lat,double lon){  
        double[] gcj02 = gps84_To_Gcj02(lat,lon);  
        double[] bd09 = gcj02_To_Bd09(gcj02[0],gcj02[1]);  
        return bd09;  
    }  

	/**
     * 百度 == 》 84
     * @param lat 
     * @param lon 
     * @return 
     */  
    public static double[] bd09_To_gps84(double lat,double lon){  
        double[] gcj02 = bd09_To_Gcj02(lat, lon);  
        double[] gps84 = gcj02_To_Gps84(gcj02[0], gcj02[1]);  
        //保留小数点后六位  
        gps84[0] = retain6(gps84[0]);  
        gps84[1] = retain6(gps84[1]);  
        return gps84;  
    }  
  
    /*
     * 保留小数点后六位 
     * @param num 
     * @return 
     */  
    private static double retain6(double num){  
        String result = String .format("%.6f", num);  
        return Double.valueOf(result);  
    }
}

参考:https://blog.csdn.net/qq_45829350/article/details/105053687

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用以下代码将OFD的base64字符串转换为PDF的base64字符串: ``` java import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.tools.imageio.ImageIOUtil; import org.ofdrw.converter.ConvertHelper; import org.ofdrw.reader.OFDReader; import org.ofdrw.reader.ResourceLocator; public class OFD2PDFBase64 { public static void main(String[] args) throws IOException { String ofdBase64 = "OFD文件的base64字符串"; // 将OFD的base64字符串转换为byte数组 byte[] ofdBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(ofdBase64); ByteArrayInputStream inputStream = new ByteArrayInputStream(ofdBytes); // 使用OFDReader读取OFD文件 OFDReader reader = new OFDReader(inputStream, new ResourceLocator() { @Override public Path locate(String s) { // 返回OFD文件中的资源路径 return Paths.get(s); } }); // 使用ConvertHelper进行OFD转PDF ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ConvertHelper.toPdf(reader, outputStream); byte[] pdfBytes = outputStream.toByteArray(); // 将PDF的byte数组转换base64字符串 String pdfBase64 = javax.xml.bind.DatatypeConverter.printBase64Binary(pdfBytes); // 如果需要将PDF转成图片,可以使用以下代码 PDDocument pdf = PDDocument.load(new ByteArrayInputStream(pdfBytes)); PDFRenderer renderer = new PDFRenderer(pdf); for (int i = 0; i < pdf.getNumberOfPages(); i++) { PDPage page = pdf.getPage(i); BufferedImage image = renderer.renderImageWithDPI(i, 300); ImageIOUtil.writeImage(image, "page-" + (i+1) + ".png", 300); } pdf.close(); } } ``` 注意,使用该方法需要引入Apache PDFBox和OFDRW的依赖库。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值