pdfbox文本内容修在网上找不到。经过几周的寻找终于找到,虽然我自己也发现这个字符编码的没弄成,参考这个后终于搞好了😊太不容易了。
记录下 方便以后使用

/**
 * 上传PDF文件并修改文件内容
 */
@PostMapping("/upload/editInvoicePdf")
public AjaxResult editInvoicePdf(MultipartFile file) throws Exception {
    try {
        // 上传文件路径
        String filePath = RuoYiConfig.getProfile()+"/InvoiceReplace";
        // 上传并返回新文件名称
        String fileName = FileUploadUtils.upload(filePath, file);
        String url = serverConfig.getUrl() + fileName;
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", url);
        ajax.put("fileName", fileName);
        ajax.put("newFileName", FileUtils.getName(fileName));
        ajax.put("originalFilename", file.getOriginalFilename());

        // 加载PDF文档
        String fileName1 = filePath+fileName.substring(fileName.indexOf("InvoiceReplace")+14);
        File file1 = ResourceUtils.getFile(fileName1);
        PDDocument pd = PDDocument.load(file1);
        // 需要的字体文件
        Map<COSName, PDFont> oldfont = new HashMap<COSName, PDFont>();
        COSName fontName = null;
        PDType0Font targetfont= PDType0Font.load(pd, new File("C:\\Windows\\Fonts\\Arial.ttf"));
        for (PDPage page : pd.getPages()) {
            PDFStreamParser pdfsp = new PDFStreamParser(page);
            pdfsp.parse();
            List<Object> tokens = pdfsp.getTokens();
            for (int j = 0; j < tokens.size(); j++) {
                //创建一个object对象去接收标记
                Object next = tokens.get( j );
                //instanceof判断其左边对象是否为其右边类的实例
                if(next  instanceof COSName) {
                    fontName= (COSName)next;
                    if(!oldfont.containsKey(fontName)) {
                        oldfont.put(fontName, page.getResources().getFont(fontName));
                    }
                }else
                if(next  instanceof COSString) {
                    COSString previous = (COSString)next;
                    try(InputStream in = new ByteArrayInputStream(previous.getBytes())){
                        StringBuffer sb = new StringBuffer();
                        while (in.available()>0) {
                            int rc = oldfont.get(fontName).readCode(in);
                            sb.append(oldfont.get(fontName).toUnicode(rc));
                        }
                        //重置COSString对象
                        if (sb.toString().contains("替换字符")) {
                            sb.delete(0, sb.length());
                            sb.append("Y替换字符");
                        }
                        previous.setValue(targetfont.encode(sb.toString()));
                        System.out.println("--Tj----"+sb.toString());
                    }
                }else if(next  instanceof COSArray) {
                    //PDF中的字符串
                    byte[] pstring = {};
                    int prej = 0;
                    COSArray previous  =(COSArray)next;
                    //循环previous
                    for (int k = 0; k < previous.size(); k++) {
                        Object arrElement = previous.getObject( k );
                        if( arrElement instanceof COSString ){
                            //COSString对象>>创建java字符串的一个新的文本字符串。
                            COSString cosString =(COSString)arrElement;
                            //将此字符串的内容作为PDF文本字符串返回。
                            if (j == prej) {
                                byte[] thisbyte = cosString.getBytes();
                                byte[] temp = new byte[pstring.length+thisbyte.length];
                                System.arraycopy(pstring, 0, temp, 0, pstring.length);
                                System.arraycopy(thisbyte, 0, temp, pstring.length, thisbyte.length);
                                pstring=temp;
                            } else {
                                prej = j;
                                pstring = cosString.getBytes();
                            }
                        }
                    }
                    try(InputStream in = new ByteArrayInputStream(pstring)){
                        StringBuffer sb = new StringBuffer();
                        while (in.available()>0) {
                            int rc = oldfont.get(fontName).readCode(in);
                            sb.append(oldfont.get(fontName).toUnicode(rc));
                        }
                        if (sb.toString().contains("被替换字符")) {
                            sb.delete(0, sb.length());
                            sb.append("替换字符");
                        }
                        System.out.println("TJ----"+sb.toString());
                        COSString cosString2 = (COSString) previous.getObject(0);
                        cosString2.setValue(targetfont.encode(sb.toString()));
                    }
                    int total = previous.size()-1;
                    for (int k = total; k > 0; k--) {
                        previous.remove(k);
                    }
                }
            }
            PDStream updatedStream = new PDStream(pd);
            OutputStream out = updatedStream.createOutputStream();
            ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
            tokenWriter.writeTokens(tokens);
            out.close();
            oldfont.forEach((k,v)->{
                page.getResources().put(k, targetfont);
            });
            page.setContents(updatedStream);
        }
        pd.save(fileName1);
        pd.close();
        return ajax;
    } catch (IOException e) {
        return AjaxResult.error(e.getMessage());
    }

}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐