生成PDF并转图片丢失中文显示的问题

问题背景

        在系统中需要对PDF模板填充数据内容并生成临时PDF,再将临时PDF文档转换为图片格式并保存(此过程无论成功还是失败都会把临时生成的PDF删除,减少不必要的存储空间)。PDF模板部分内容截图如下:        

但是最终生成的图片中,却缺失了填充内容的中文信息,如下图所示:

查找问题

        一开始一直怀疑是使用因为使用itextpdf的jar包在填充PDF模板生成PDF的时候出问题的,因为当时搜了一下网上确实有很多因为使用了这种jar包而导致中文缺失或是乱码的问题。因此花了一段时间一直在这个方面查找和解决问题,包括引入itextpdf的字体包itext-asian来解决此问题,但最终生成的图片还是没有中文。最终,当把代码中删除临时PDF该操作放开,来将生成好的临时PDF和最后图片进行比对。最后终于发现是PDF转图片的过程中丢失了填充内容的中文。

解决问题

        1.在将PDF转为图片时,个人使用的是apache开源pdfbox的jar包(问题出在此)。

        2.查找各相关文档,发现大部分解决方法都是复写源码来指定字体库,当然还有其他方案,就是本地系统安装相关字体库,亦能解决问题。

代码实现

        现贴出解决该需求(根据PDF模板生成PDF,再将PDF转为图片)以及解决相关问题(PDF转图片丢失中文)的相关代码。

        1.maven配置:

         说明:1.itextpdf的两个包是用于PDF模板生成PDF用的,itext-asian可使能兼容中文内容。

                2.pdfbox是用于PDF转图片的(亦是我们要解决不能显示中文内容的问题)。

        2.根据PDF模板生成PDF工具类 

public class PdfUtils {

    private static final Logger logger = LoggerFactory.getLogger(PdfUtils.class);


    public static ByteArrayOutputStream generatePdf(String templatePath, Map<String, String> dataMap, Map<String, String> imgMap) {
        try {
            FileInputStream inputStream = new FileInputStream(templatePath);
            Throwable var4 = null;

            ByteArrayOutputStream var5;
            try {
                var5 = generatePdf((InputStream)inputStream, dataMap, imgMap);
            } catch (Throwable var15) {
                var4 = var15;
                throw var15;
            } finally {
                if (inputStream != null) {
                    if (var4 != null) {
                        try {
                            inputStream.close();
                        } catch (Throwable var14) {
                            var4.addSuppressed(var14);
                        }
                    } else {
                        inputStream.close();
                    }
                }

            }

            return var5;
        } catch (IOException var17) {
            logger.error("生成PDF异常, e:", var17);
            throw new PDFException("生成PDF异常");
        }
    }

    public static ByteArrayOutputStream generatePdf(InputStream templateInputStream, Map<String, String> dataMap, Map<String, String> imgMap) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            Throwable var6 = null;

            ByteArrayOutputStream var29;
            try {
                PdfReader reader = new PdfReader(templateInputStream);
                PdfStamper stamper = new PdfStamper(reader, bos);
                AcroFields form = stamper.getAcroFields();
                BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
                form.addSubstitutionFont(bfChinese);
                Iterator var9;
                String key;
                String value;
                if (dataMap != null) {
                    var9 = dataMap.keySet().iterator();

                    while(var9.hasNext()) {
                        key = (String)var9.next();
                        value = (String)dataMap.get(key);
                        form.setField(key, value);
                    }
                }

                if (imgMap != null) {
                    var9 = imgMap.keySet().iterator();

                    while(var9.hasNext()) {
                        key = (String)var9.next();
                        value = (String)imgMap.get(key);
                        int pageNo = ((AcroFields.FieldPosition)form.getFieldPositions(key).get(0)).page;
                        Rectangle signRect = ((AcroFields.FieldPosition)form.getFieldPositions(key).get(0)).position;
                        float x = signRect.getLeft();
                        float y = signRect.getBottom();
                        Image image = Image.getInstance(value);
                        PdfContentByte under = stamper.getOverContent(pageNo);
                        image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                        image.setAbsolutePosition(x, y);
                        under.addImage(image);
                    }
                }

                stamper.setFormFlattening(true);
                stamper.close();
                var29 = bos;
            } catch (Throwable var26) {
                var6 = var26;
                throw var26;
            } finally {
                if (bos != null) {
                    if (var6 != null) {
                        try {
                            bos.close();
                        } catch (Throwable var25) {
                            var6.addSuppressed(var25);
                        }
                    } else {
                        bos.close();
                    }
                }

            }

            return var29;
        } catch (Exception var28) {
            logger.error("生成PDF异常, e:", var28);
            throw new PDFException("生成PDF异常");
        }
    }

    public static void generatePdfFile(String templatePath, Map<String, String> dataMap, Map<String, String> imgMap, String newPdfPath) {
        try {
            FileOutputStream out = new FileOutputStream(newPdfPath);
            Throwable var5 = null;

            try {
                ByteArrayOutputStream bos = generatePdf(templatePath, dataMap, imgMap);
                Throwable var7 = null;

                try {
                    Document doc = new Document();
                    PdfCopy copy = new PdfCopy(doc, out);
                    doc.open();
                    PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
                    copy.addPage(importPage);
                    doc.close();
                } catch (Throwable var34) {
                    var7 = var34;
                    throw var34;
                } finally {
                    if (bos != null) {
                        if (var7 != null) {
                            try {
                                bos.close();
                            } catch (Throwable var33) {
                                var7.addSuppressed(var33);
                            }
                        } else {
                            bos.close();
                        }
                    }

                }
            } catch (Throwable var36) {
                var5 = var36;
                throw var36;
            } finally {
                if (out != null) {
                    if (var5 != null) {
                        try {
                            out.close();
                        } catch (Throwable var32) {
                            var5.addSuppressed(var32);
                        }
                    } else {
                        out.close();
                    }
                }

            }

        } catch (Exception var38) {
            logger.error("生成PDF异常, e:", var38);
            throw new PDFException("生成PDF异常");
        }
    }

    public static InputStream generatePdfIntoInputStream(InputStream templateInputStream, Map<String, String> dataMap, Map<String, String> imgMap) {
        byte[] fileBytes = generatePdfIntoByte(templateInputStream, dataMap, imgMap);
        return new ByteArrayInputStream(fileBytes);
    }

    public static byte[] generatePdfIntoByte(InputStream templateInputStream, Map<String, String> dataMap, Map<String, String> imgMap) {
        ByteArrayOutputStream outputStream = generatePdf(templateInputStream, dataMap, imgMap);
        return outputStream.toByteArray();
    }

}

        3.根据PDF转换为图片工具类 

public class PdfToImagesUtil{

    public static final String PNG = "png";

    private static final Logger logger = LoggerFactory.getLogger(PdfToImagesUtil.class);

    /**
     * 转换全部的pdf
     * @param fileAddress 文件地址
     * @param filename PDF文件名
     * @param type 图片类型
     */
    public static boolean pdf2png(String fileAddress,String filename,String type) {
        boolean isSuccess = false;
        // 将pdf装图片 并且自定义图片得格式大小
         File file = new File(fileAddress + "/" + filename + ".pdf");
        try {
            PDDocument pDoc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(pDoc);

            BufferedImage image = renderer.renderImageWithDPI(0, 144); // Windows native DPI
            // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
            isSuccess = ImageIO.write(image, type, new File(fileAddress + "/" + filename + "." + type));
            pDoc.close();
            return isSuccess;
        } catch (IOException e) {
            logger.error("pdf转换为图片失败:", e);
            return isSuccess;
        }
    }

    /**
     *自由确定起始页和终止页
     * @param fileAddress 文件地址
     * @param filename pdf文件名
     * @param indexOfStart 开始页  开始转换的页码,从0开始
     * @param indexOfEnd 结束页  停止转换的页码,-1为全部
     * @param type 图片类型
     */
    public static void pdf2png(String fileAddress,String filename,int indexOfStart,int indexOfEnd,String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress+"\\"+filename+".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = indexOfStart; i < indexOfEnd; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));
            }
        } catch (IOException e) {
            logger.error("pdf转换为图片失败:", e);
        }
    }

}

        4.开始解决PDF转图片不能显示中文的问题。

                1.在项目里建一个与源码包名一样的路径及文件FontMapperImpl.java

                

                 说明:个人是把字体库和pdf模板文件放在resources下,放在此文件夹下,maven还需再加一个配置,来防止maven打包时将字体库和pdf模板文件编码打包,导致字体包和pdf模板被编译转码破坏不可用。   

                 2.复写源码的FontMapperImpl.java文件

                 代码如下:

package org.apache.pdfbox.pdmodel.font;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;

import org.apache.fontbox.FontBoxFont;
import org.apache.fontbox.ttf.OpenTypeFont;
import org.apache.fontbox.ttf.TTFParser;
import org.apache.fontbox.ttf.TrueTypeFont;
import org.apache.fontbox.type1.Type1Font;

final class FontMapperImpl implements FontMapper {
    private static final FontCache fontCache = new FontCache();
    private FontProvider fontProvider;
    private Map<String, FontInfo> fontInfoByName;
    private final TrueTypeFont lastResortFont;
    private final Map<String, List<String>> substitutes = new HashMap();

    FontMapperImpl() {
        this.substitutes.put("Courier", Arrays.asList("CourierNew", "CourierNewPSMT", "LiberationMono", "NimbusMonL-Regu"));
        this.substitutes.put("Courier-Bold", Arrays.asList("CourierNewPS-BoldMT", "CourierNew-Bold", "LiberationMono-Bold", "NimbusMonL-Bold"));
        this.substitutes.put("Courier-Oblique", Arrays.asList("CourierNewPS-ItalicMT", "CourierNew-Italic", "LiberationMono-Italic", "NimbusMonL-ReguObli"));
        this.substitutes.put("Courier-BoldOblique", Arrays.asList("CourierNewPS-BoldItalicMT", "CourierNew-BoldItalic", "LiberationMono-BoldItalic", "NimbusMonL-BoldObli"));
        this.substitutes.put("Helvetica", Arrays.asList("ArialMT", "Arial", "LiberationSans", "NimbusSanL-Regu"));
        this.substitutes.put("Helvetica-Bold", Arrays.asList("Arial-BoldMT", "Arial-Bold", "LiberationSans-Bold", "NimbusSanL-Bold"));
        this.substitutes.put("Helvetica-Oblique", Arrays.asList("Arial-ItalicMT", "Arial-Italic", "Helvetica-Italic", "LiberationSans-Italic", "NimbusSanL-ReguItal"));
        this.substitutes.put("Helvetica-BoldOblique", Arrays.asList("Arial-BoldItalicMT", "Helvetica-BoldItalic", "LiberationSans-BoldItalic", "NimbusSanL-BoldItal"));
        this.substitutes.put("Times-Roman", Arrays.asList("TimesNewRomanPSMT", "TimesNewRoman", "TimesNewRomanPS", "LiberationSerif", "NimbusRomNo9L-Regu"));
        this.substitutes.put("Times-Bold", Arrays.asList("TimesNewRomanPS-BoldMT", "TimesNewRomanPS-Bold", "TimesNewRoman-Bold", "LiberationSerif-Bold", "NimbusRomNo9L-Medi"));
        this.substitutes.put("Times-Italic", Arrays.asList("TimesNewRomanPS-ItalicMT", "TimesNewRomanPS-Italic", "TimesNewRoman-Italic", "LiberationSerif-Italic", "NimbusRomNo9L-ReguItal"));
        this.substitutes.put("Times-BoldItalic", Arrays.asList("TimesNewRomanPS-BoldItalicMT", "TimesNewRomanPS-BoldItalic", "TimesNewRoman-BoldItalic", "LiberationSerif-BoldItalic", "NimbusRomNo9L-MediItal"));
        this.substitutes.put("Symbol", Arrays.asList("Symbol", "SymbolMT", "StandardSymL"));
        this.substitutes.put("ZapfDingbats", Arrays.asList("ZapfDingbatsITC", "Dingbats", "MS-Gothic"));
        this.substitutes.put("STSong-Light", Arrays.asList("STSONG-light","DengXian"));//自己加的
        Iterator var1 = Standard14Fonts.getNames().iterator();

        while(var1.hasNext()) {
            String baseName = (String)var1.next();
            if (!this.substitutes.containsKey(baseName)) {
                String mappedName = Standard14Fonts.getMappedFontName(baseName);
                this.substitutes.put(baseName, this.copySubstitutes(mappedName));
            }
        }

        try {
            String ttfName = "/pdftemplates/font/STSONG-light.ttf";
            InputStream ttfStream = FontMapperImpl.class.getResourceAsStream(ttfName);
            TTFParser ttfParser = new TTFParser();
            System.out.println("----->>读取自定义字体:" + ttfName);
            this.lastResortFont = ttfParser.parse(ttfStream);
        } catch (IOException var5) {
            throw new RuntimeException(var5);
        }
    }

    public synchronized void setProvider(FontProvider fontProvider) {
        this.fontInfoByName = this.createFontInfoByName(fontProvider.getFontInfo());
        this.fontProvider = fontProvider;
    }

    public synchronized FontProvider getProvider() {
        if (this.fontProvider == null) {
            this.setProvider(FontMapperImpl.DefaultFontProvider.INSTANCE);
        }

        return this.fontProvider;
    }

    public FontCache getFontCache() {
        return fontCache;
    }

    private Map<String, FontInfo> createFontInfoByName(List<? extends FontInfo> fontInfoList) {
        Map<String, FontInfo> map = new LinkedHashMap();
        Iterator var3 = fontInfoList.iterator();

        while(var3.hasNext()) {
            FontInfo info = (FontInfo)var3.next();
            Iterator var5 = this.getPostScriptNames(info.getPostScriptName()).iterator();

            while(var5.hasNext()) {
                String name = (String)var5.next();
                map.put(name, info);
            }
        }

        return map;
    }

    private Set<String> getPostScriptNames(String postScriptName) {
        Set<String> names = new HashSet();
        names.add(postScriptName);
        names.add(postScriptName.replaceAll("-", ""));
        return names;
    }

    private List<String> copySubstitutes(String postScriptName) {
        return new ArrayList((Collection)this.substitutes.get(postScriptName));
    }

    public void addSubstitute(String match, String replace) {
        if (!this.substitutes.containsKey(match)) {
            this.substitutes.put(match, new ArrayList());
        }

        ((List)this.substitutes.get(match)).add(replace);
    }

    private List<String> getSubstitutes(String postScriptName) {
        List<String> subs = (List)this.substitutes.get(postScriptName.replaceAll(" ", ""));
        return subs != null ? subs : Collections.emptyList();
    }

    private String getFallbackFontName(PDFontDescriptor fontDescriptor) {
        String fontName;
        if (fontDescriptor != null) {
            boolean isBold = false;
            String name = fontDescriptor.getFontName();
            if (name != null) {
                String lower = fontDescriptor.getFontName().toLowerCase();
                isBold = lower.contains("bold") || lower.contains("black") || lower.contains("heavy");
            }

            if (fontDescriptor.isFixedPitch()) {
                fontName = "Courier";
                if (isBold && fontDescriptor.isItalic()) {
                    fontName = fontName + "-BoldOblique";
                } else if (isBold) {
                    fontName = fontName + "-Bold";
                } else if (fontDescriptor.isItalic()) {
                    fontName = fontName + "-Oblique";
                }
            } else if (fontDescriptor.isSerif()) {
                fontName = "Times";
                if (isBold && fontDescriptor.isItalic()) {
                    fontName = fontName + "-BoldItalic";
                } else if (isBold) {
                    fontName = fontName + "-Bold";
                } else if (fontDescriptor.isItalic()) {
                    fontName = fontName + "-Italic";
                } else {
                    fontName = fontName + "-Roman";
                }
            } else {
                fontName = "Helvetica";
                if (isBold && fontDescriptor.isItalic()) {
                    fontName = fontName + "-BoldOblique";
                } else if (isBold) {
                    fontName = fontName + "-Bold";
                } else if (fontDescriptor.isItalic()) {
                    fontName = fontName + "-Oblique";
                }
            }
        } else {
            fontName = "Times-Roman";
        }

        return fontName;
    }

    public FontMapping<TrueTypeFont> getTrueTypeFont(String baseFont, PDFontDescriptor fontDescriptor) {
        TrueTypeFont ttf = (TrueTypeFont)this.findFont(FontFormat.TTF, baseFont);
        if (ttf != null) {
            return new FontMapping(ttf, false);
        } else {
            String fontName = this.getFallbackFontName(fontDescriptor);
            ttf = (TrueTypeFont)this.findFont(FontFormat.TTF, fontName);
            if (ttf == null) {
                ttf = this.lastResortFont;
            }

            return new FontMapping(ttf, true);
        }
    }

    public FontMapping<FontBoxFont> getFontBoxFont(String baseFont, PDFontDescriptor fontDescriptor) {
        FontBoxFont font = this.findFontBoxFont(baseFont);
        if (font != null) {
            return new FontMapping(font, false);
        } else {
            String fallbackName = this.getFallbackFontName(fontDescriptor);
            FontBoxFont font2 = this.findFontBoxFont(fallbackName);
            if (font2 == null) {
                font = this.lastResortFont;
            }else {
                font= font2;
            }

            return new FontMapping((FontBoxFont)font, true);
        }
    }

    private FontBoxFont findFontBoxFont(String postScriptName) {
        Type1Font t1 = (Type1Font)this.findFont(FontFormat.PFB, postScriptName);
        if (t1 != null) {
            return t1;
        } else {
            TrueTypeFont ttf = (TrueTypeFont)this.findFont(FontFormat.TTF, postScriptName);
            if (ttf != null) {
                return ttf;
            } else {
                OpenTypeFont otf = (OpenTypeFont)this.findFont(FontFormat.OTF, postScriptName);
                return otf != null ? otf : null;
            }
        }
    }

    private FontBoxFont findFont(FontFormat format, String postScriptName) {
        if (postScriptName == null) {
            return null;
        } else {
            if (this.fontProvider == null) {
                this.getProvider();
            }

            FontInfo info = this.getFont(format, postScriptName);
            if (info != null) {
                return info.getFont();
            } else {
                info = this.getFont(format, postScriptName.replaceAll("-", ""));
                if (info != null) {
                    return info.getFont();
                } else {
                    Iterator var4 = this.getSubstitutes(postScriptName).iterator();

                    do {
                        if (!var4.hasNext()) {
                            info = this.getFont(format, postScriptName.replaceAll(",", "-"));
                            if (info != null) {
                                return info.getFont();
                            }

                            info = this.getFont(format, postScriptName + "-Regular");
                            if (info != null) {
                                return info.getFont();
                            }

                            return null;
                        }

                        String substituteName = (String)var4.next();
                        info = this.getFont(format, substituteName);
                    } while(info == null);

                    return info.getFont();
                }
            }
        }
    }

    private FontInfo getFont(FontFormat format, String postScriptName) {
        if (postScriptName.contains("+")) {
            postScriptName = postScriptName.substring(postScriptName.indexOf(43) + 1);
        }

        FontInfo info = (FontInfo)this.fontInfoByName.get(postScriptName);
        return info != null && info.getFormat() == format ? info : null;
    }

    public CIDFontMapping getCIDFont(String baseFont, PDFontDescriptor fontDescriptor, PDCIDSystemInfo cidSystemInfo) {
        OpenTypeFont otf1 = (OpenTypeFont)this.findFont(FontFormat.OTF, baseFont);
        if (otf1 != null) {
            return new CIDFontMapping(otf1, (FontBoxFont)null, false);
        } else {
            TrueTypeFont ttf = (TrueTypeFont)this.findFont(FontFormat.TTF, baseFont);
            if (ttf != null) {
                return new CIDFontMapping((OpenTypeFont)null, ttf, false);
            } else {
                /*if (cidSystemInfo != null) {
                    String collection = cidSystemInfo.getRegistry() + "-" + cidSystemInfo.getOrdering();
                    if (collection.equals("Adobe-GB1") || collection.equals("Adobe-CNS1") || collection.equals("Adobe-Japan1") || collection.equals("Adobe-Korea1")) {
                        PriorityQueue<FontMapperImpl.FontMatch> queue = this.getFontMatches(fontDescriptor, cidSystemInfo);
                        FontMapperImpl.FontMatch bestMatch = (FontMapperImpl.FontMatch)queue.poll();
                        if (bestMatch != null) {
                            FontBoxFont font = bestMatch.info.getFont();
                            if (font instanceof OpenTypeFont) {
                                return new CIDFontMapping((OpenTypeFont)font, (FontBoxFont)null, true);
                            }

                            if (font != null) {
                                return new CIDFontMapping((OpenTypeFont)null, font, true);
                            }
                        }
                    }
                }*/

                return new CIDFontMapping((OpenTypeFont)null, this.lastResortFont, true);
            }
        }
    }

    private PriorityQueue<FontMapperImpl.FontMatch> getFontMatches(PDFontDescriptor fontDescriptor, PDCIDSystemInfo cidSystemInfo) {
        PriorityQueue<FontMapperImpl.FontMatch> queue = new PriorityQueue(20);
        Iterator var4 = this.fontInfoByName.values().iterator();

        while(true) {
            FontMapperImpl.FontMatch match;
            while(true) {
                FontInfo info;
                do {
                    if (!var4.hasNext()) {
                        return queue;
                    }

                    info = (FontInfo)var4.next();
                } while(cidSystemInfo != null && !this.isCharSetMatch(cidSystemInfo, info));

                match = new FontMapperImpl.FontMatch(info);
                if (fontDescriptor.getPanose() != null && info.getPanose() != null) {
                    PDPanoseClassification panose = fontDescriptor.getPanose().getPanose();
                    if (panose.getFamilyKind() != info.getPanose().getFamilyKind()) {
                        break;
                    }

                    if (panose.getFamilyKind() == 0 && (info.getPostScriptName().toLowerCase().contains("barcode") || info.getPostScriptName().startsWith("Code")) && !this.probablyBarcodeFont(fontDescriptor)) {
                        continue;
                    }

                    if (panose.getSerifStyle() == info.getPanose().getSerifStyle()) {
                        match.score += 2.0D;
                    } else if (panose.getSerifStyle() >= 2 && panose.getSerifStyle() <= 5 && info.getPanose().getSerifStyle() >= 2 && info.getPanose().getSerifStyle() <= 5) {
                        ++match.score;
                    } else if (panose.getSerifStyle() >= 11 && panose.getSerifStyle() <= 13 && info.getPanose().getSerifStyle() >= 11 && info.getPanose().getSerifStyle() <= 13) {
                        ++match.score;
                    } else if (panose.getSerifStyle() != 0 && info.getPanose().getSerifStyle() != 0) {
                        --match.score;
                    }

                    int weight = info.getPanose().getWeight();
                    int weightClass = info.getWeightClassAsPanose();
                    if (Math.abs(weight - weightClass) > 2) {
                        weight = weightClass;
                    }

                    if (panose.getWeight() == weight) {
                        match.score += 2.0D;
                    } else if (panose.getWeight() > 1 && weight > 1) {
                        float dist = (float)Math.abs(panose.getWeight() - weight);
                        match.score += 1.0D - (double)dist * 0.5D;
                    }
                    break;
                }

                if (fontDescriptor.getFontWeight() > 0.0F && info.getWeightClass() > 0) {
                    float dist = Math.abs(fontDescriptor.getFontWeight() - (float)info.getWeightClass());
                    match.score += 1.0D - (double)(dist / 100.0F) * 0.5D;
                }
                break;
            }

            queue.add(match);
        }
    }

    private boolean probablyBarcodeFont(PDFontDescriptor fontDescriptor) {
        String ff = fontDescriptor.getFontFamily();
        if (ff == null) {
            ff = "";
        }

        String fn = fontDescriptor.getFontName();
        if (fn == null) {
            fn = "";
        }

        return ff.startsWith("Code") || ff.toLowerCase().contains("barcode") || fn.startsWith("Code") || fn.toLowerCase().contains("barcode");
    }

    private boolean isCharSetMatch(PDCIDSystemInfo cidSystemInfo, FontInfo info) {
        if (info.getCIDSystemInfo() != null) {
            return info.getCIDSystemInfo().getRegistry().equals(cidSystemInfo.getRegistry()) && info.getCIDSystemInfo().getOrdering().equals(cidSystemInfo.getOrdering());
        } else {
            long codePageRange = info.getCodePageRange();
            long JIS_JAPAN = 131072L;
            long CHINESE_SIMPLIFIED = 262144L;
            long KOREAN_WANSUNG = 524288L;
            long CHINESE_TRADITIONAL = 1048576L;
            long KOREAN_JOHAB = 2097152L;
            if (cidSystemInfo.getOrdering().equals("GB1") && (codePageRange & CHINESE_SIMPLIFIED) == CHINESE_SIMPLIFIED) {
                return true;
            } else if (cidSystemInfo.getOrdering().equals("CNS1") && (codePageRange & CHINESE_TRADITIONAL) == CHINESE_TRADITIONAL) {
                return true;
            } else if (cidSystemInfo.getOrdering().equals("Japan1") && (codePageRange & JIS_JAPAN) == JIS_JAPAN) {
                return true;
            } else {
                return cidSystemInfo.getOrdering().equals("Korea1") && (codePageRange & KOREAN_WANSUNG) == KOREAN_WANSUNG || (codePageRange & KOREAN_JOHAB) == KOREAN_JOHAB;
            }
        }
    }

    private FontMapperImpl.FontMatch printMatches(PriorityQueue<FontMapperImpl.FontMatch> queue) {
        FontMapperImpl.FontMatch bestMatch = (FontMapperImpl.FontMatch)queue.peek();
        System.out.println("-------");

        while(!queue.isEmpty()) {
            FontMapperImpl.FontMatch match = (FontMapperImpl.FontMatch)queue.poll();
            FontInfo info = match.info;
            System.out.println(match.score + " | " + info.getMacStyle() + " " + info.getFamilyClass() + " " + info.getPanose() + " " + info.getCIDSystemInfo() + " " + info.getPostScriptName() + " " + info.getFormat());
        }

        System.out.println("-------");
        return bestMatch;
    }

    private static class FontMatch implements Comparable<FontMapperImpl.FontMatch> {
        double score;
        final FontInfo info;

        FontMatch(FontInfo info) {
            this.info = info;
        }

        public int compareTo(FontMapperImpl.FontMatch match) {
            return Double.compare(match.score, this.score);
        }
    }

    private static class DefaultFontProvider {
        private static final FontProvider INSTANCE;

        private DefaultFontProvider() {
        }

        static {
            INSTANCE = new FileSystemFontProvider(FontMapperImpl.fontCache);
        }
    }
}

                 说明:中间还注释了一段代码,即没有字体库会使用系统默认字体库的代码。各位看情况决定在各自系统中是否放开。

        5.最终效果如下:

        

总结说明

        1.个人非常不建议使用这种方式,因为此方式,一是乱了自己项目的结构,项目结构很难看,要是再遇到其他问题也是这么做,加各种开源项目的包名路径,大家可以想象最终项目结构了;二是需要在项目里使用字体包,字体包也很大,一般都是10~15m左右,若是使用多个字体包,那最后打的包也很大。好处是不是所有服务器都有对应的字体包,那运行在各环境也能正常显示中文字体,可以不需要麻烦运维在生产上去安装各种字体包(个人也是因为这原因才使用这种方式)。

        2.个人推荐的方式,一是重写需要修改的源码部分并重新打包,使用特殊的版本号上传至maven私服,仅供自己项目使用;二是在对应系统环境安装所需字体包,这种亦是最方便的。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值