PDFBOX(2.0.24) 修改文本内容 JAVA 字体问题
·
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());
}
}
更多推荐

所有评论(0)