如何解决PDFcopy文本乱码的问题!

本文介绍了使用汉王PDFCOR软件解决PDF文件中复制文本乱码问题的步骤。通过下载安装软件、将PDF文件拖入软件进行扫描、选择需要复制的文本并执行F8操作,即可有效避免乱码现象。

相信大家在平时应该碰到过自己想在PDF中想要copy文本的时候,但是paste的时候发现文本已经乱码了!这是为什么呢?具体原因我也不是很清楚。但是应该是编码的问题把??今天经过一位童鞋的介绍接触了汉王PDF COR这款软件,可以有效解决PDFcopy文本乱码的问题。现在总结下步骤把:

1.先去下载安装文件把。天空,华军都有下的。

2.把PDF文件拖到该软件职工来,它会自动进行扫描。

3.选中你需要copy的文本。按F8执行,就会在上面出现一个窗口。copy。。。

4,完工!OK!

 

package com.hvlink.service.impl; import com.alibaba.nacos.common.utils.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.hvlink.entity.dto.asn.AsnPackDTO; import com.hvlink.entity.param.asn.AsnPackExportParam; import com.hvlink.entity.param.asn.AsnPackLabelParam; import com.hvlink.entity.po.asn.AsnPackPO; import com.hvlink.entity.vo.asn.AsnPackLabelVO; import com.hvlink.mapper.asn.AsnPackMapper; import com.hvlink.pagination.PageResult; import com.hvlink.service.IAsnPackService; import com.hvlink.utils.BeanCopyUtils; import com.hvlink.utils.QRCodeUtils; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.*; import java.util.stream.Collectors; /** * ASN包装信息(AsnPack)表服务实现类 * * @author sunzhuang * @since 2025-09-23 16:39:02 */ @Slf4j @RequiredArgsConstructor @Service("asnPackService") public class AsnPackServiceImpl extends ServiceImpl<AsnPackMapper, AsnPackPO> implements IAsnPackService { private final AsnPackMapper asnPackMapper; /** * 查询标签信息 * * @param asnPackLabelParam 请求参数 * @return 查询结果 */ @Override public PageResult<AsnPackLabelVO> queryPage(AsnPackLabelParam asnPackLabelParam) { // 查询标签数据 Page<AsnPackDTO> page = new Page<>(asnPackLabelParam.getPageIndex(), asnPackLabelParam.getPageSize()); Page<AsnPackDTO> dtoPage = asnPackMapper.queryLabelPage(page, asnPackLabelParam); // 转换 DTO 到 VO List<AsnPackLabelVO> voList = Collections.emptyList(); if (!CollectionUtils.isEmpty(dtoPage.getRecords())) { voList = dtoPage.getRecords().stream() .map(dto -> BeanCopyUtils.copyBean(dto, AsnPackLabelVO.class)) .collect(Collectors.toList()); } // 构建分页结果 PageResult<AsnPackLabelVO> result = new PageResult<>(); result.setRecords(voList); result.setTotal(dtoPage.getTotal()); result.setPageIndex(asnPackLabelParam.getPageIndex()); result.setPageSize(asnPackLabelParam.getPageSize()); return result; } @Override public Mono<ResponseEntity<Resource>> exportLabels(AsnPackExportParam exportParam) { return Mono.defer(() -> { try { // 参数验证 if (exportParam == null || exportParam.getIds() == null || exportParam.getIds().isEmpty()) { return Mono.error(new IllegalArgumentException("导出参数或ID列表不能为空")); } // 查询导出数据 List<AsnPackDTO> exportData = asnPackMapper.selectByIds(exportParam.getIds()); if (exportData.isEmpty()) { return Mono.error(new RuntimeException("未找到导出数据")); } // 验证导出类型 if (!isValidExportType(exportParam.getExportType())) { return Mono.error(new IllegalArgumentException("不支持的导出类型: " + exportParam.getExportType())); } // 根据导出类型选择模板 String templatePath = getTemplatePath(exportParam.getExportType()); // 生成PDF字节数组 byte[] pdfBytes = generatePdfBytes(exportData, exportParam.getExportType(), templatePath); // 创建资源 Resource resource = new ByteArrayResource(pdfBytes); // 设置响应头 String fileName = buildFileName(exportParam.getExportType()); ResponseEntity<Resource> responseEntity = ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"") .contentType(MediaType.APPLICATION_PDF) .contentLength(pdfBytes.length) .body(resource); return Mono.just(responseEntity); } catch (Exception e) { log.error("标签导出失败", e); return Mono.error(new RuntimeException("标签导出失败: " + e.getMessage())); } }); } private String getTemplatePath(String exportType) { switch (exportType.toUpperCase()) { case "P": return "static/templates/P.pdf"; // 托标签模板 case "C": return "static/templates/C.pdf"; // 箱标签模板 case "B": return "static/templates/B.pdf"; // 包标签模板 default: throw new IllegalArgumentException("不支持的导出类型: " + exportType); } } private boolean isValidExportType(String exportType) { if (exportType == null) return false; String type = exportType.toUpperCase(); return type.equals("P") || type.equals("C") || type.equals("B"); } private String buildFileName(String exportType) { String typeName = ""; switch (exportType.toUpperCase()) { case "P": typeName = "托标签"; break; case "C": typeName = "箱标签"; break; case "B": typeName = "包标签"; break; default: typeName = "标签"; } // 构建文件名 String fileName = typeName + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".pdf"; try { // 对文件名进行URL编码 return java.net.URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); } catch (Exception e) { log.warn("文件名编码失败,使用默认文件名", e); return "export_" + System.currentTimeMillis() + ".pdf"; } } private byte[] generatePdfBytes(List<AsnPackDTO> data, String exportType, String templatePath) throws Exception { ClassPathResource templateResource = new ClassPathResource(templatePath); if (!templateResource.exists()) { throw new RuntimeException("模板文件不存在: " + templatePath); } try (InputStream templateStream = templateResource.getInputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { PdfReader reader = new PdfReader(templateStream); PdfStamper stamper = new PdfStamper(reader, outputStream); AcroFields form = stamper.getAcroFields(); // 添加中文字体支持 BaseFont simSunFont = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); form.addSubstitutionFont(simSunFont); // 填充第一个数据项 AsnPackDTO item = data.get(0); fillFormFields(form, item, exportType); // 添加二维码到指定位置 addQRCode(stamper, form, item, exportType); stamper.setFormFlattening(true); // 将表单转为静态文本 stamper.close(); // 关闭 stamper 会自动写入修改后的内容 reader.close(); return outputStream.toByteArray(); } } private void fillFormFields(AcroFields form, AsnPackDTO item, String exportType) throws Exception { Map<String, String> fieldValues = buildFieldValues(item, exportType); log.info("要填充的数据: {}", fieldValues); // 填充表单字段 for (Map.Entry<String, String> entry : fieldValues.entrySet()) { String fieldName = entry.getKey(); String fieldValue = entry.getValue(); if (form.getFields().containsKey(fieldName)) { if (StringUtils.hasText(fieldValue)) { try { form.setField(fieldName, fieldValue); log.info("成功填充字段: {} = {}", fieldName, fieldValue); } catch (Exception e) { log.error("填充字段失败: {}, 值: {}", fieldName, fieldValue, e); } } else { log.warn("字段值为空: {}", fieldName); } } else { log.warn("未找到表单字段: {}", fieldName); } } } private Map<String, String> buildFieldValues(AsnPackDTO item, String exportType) { Map<String, String> values = new HashMap<>(); // 公共字段 values.put("part_desc", item.getPartDesc()); values.put("part_code", item.getPartCode()); values.put("supplier_name", item.getSupplierName()); values.put("supplier_code", item.getSupplierCode()); values.put("order_no", item.getAsnNo()); values.put("production_batch", item.getProductionBatch()); values.put("case_code", generateCaseCode(item, exportType)); values.put("remark", item.getRemark()); // 数量相关字段 switch (exportType.toUpperCase()) { case "P": values.put("quantity", formatQuantity(item.getQuantity())); values.put("pack_quantity", formatQuantity(item.getPackQuantity())); values.put("unique_code", generateUniqueCode("P", item.getSupplierCode())); values.put("master_label", "MASTER LABEL " + item.getWarehouseCode()); break; case "C": values.put("quantity", formatQuantity(item.getQuantity())); values.put("pack_quantity", formatQuantity(item.getPackQuantity())); values.put("unique_code", generateUniqueCode("C", item.getSupplierCode())); break; case "B": values.put("quantity", formatQuantity(item.getQuantity())); values.put("pack_quantity", formatQuantity(item.getPackQuantity())); values.put("unique_code", generateUniqueCode("B", item.getSupplierCode())); break; } return values; } private String generateCaseCode(AsnPackDTO item, String exportType) { switch (exportType.toUpperCase()) { case "P": return "1/1"; // X/Y格式 case "C": return "1/5-1"; // X/Y-Z格式 case "B": return "1/10-C-1"; // X/Y-C-Z格式 default: return item.getCaseCode(); } } private String generateUniqueCode(String prefix, String supplierCode) { SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd"); String dateStr = sdf.format(new Date()); String sequence = String.format("%06d", System.currentTimeMillis() % 1000000); return prefix + supplierCode + dateStr + sequence; } private String formatQuantity(Double quantity) { return quantity != null ? String.valueOf(quantity) : "0"; } private void addQRCode(PdfStamper stamper, AcroFields form, AsnPackDTO item, String exportType) throws Exception { try { String uniqueCode = generateUniqueCode( exportType.equals("P") ? "P" : exportType.equals("C") ? "C" : "B", item.getSupplierCode() ); // 生成二维码 ByteArrayOutputStream qrCodeStream = QRCodeUtils.generateQRCode(uniqueCode, 100, 100); Image qrCodeImage = Image.getInstance(qrCodeStream.toByteArray()); // 获取字段位置 List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions("QRcode"); if (fieldPositions == null || fieldPositions.isEmpty()) { log.warn("未找到 QRcode 字段的位置信息"); return; } AcroFields.FieldPosition position = fieldPositions.get(0); int pageNo = position.page; Rectangle rect = position.position; PdfContentByte canvas = stamper.getOverContent(pageNo); // 使用上层绘制,避免干扰底层 qrCodeImage.setAbsolutePosition(rect.getLeft(), rect.getBottom()); qrCodeImage.scaleToFit(rect.getWidth(), rect.getHeight()); canvas.addImage(qrCodeImage); } catch (Exception e) { log.error("添加二维码失败", e); throw e; // 显式抛出便于调试 } } } 请把我的导出PDF功能完全根据下面的代码修改,只保留包标签模板的填充和导出,我需要这样测试,并且不要二维码生成 import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; public class Snippet { // 利用模板生成pdf public static void fillTemplate() { // 模板路径 String templatePath = "E:/测试3.pdf"; // 生成的新文件路径 String newPDFPath = "E:/ceshi.pdf"; PdfReader reader; FileOutputStream out; ByteArrayOutputStream bos; PdfStamper stamper; try { out = new FileOutputStream(newPDFPath);// 输出流 reader = new PdfReader(templatePath);// 读取pdf模板 bos = new ByteArrayOutputStream(); stamper = new PdfStamper(reader, bos); AcroFields form = stamper.getAcroFields(); String[] str = { "123456789", "TOP__ONE", "男", "1991-01-01", "130222111133338888", "河北省保定市" }; int i = 0; java.util.Iterator<String> it = form.getFields().keySet().iterator(); while (it.hasNext()) { String name = it.next().toString(); System.out.println(name); form.setField(name, str[i++]); } stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true stamper.close(); 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 (IOException e) { System.out.println(1); } catch (DocumentException e) { System.out.println(2); } } public static void main(String[] args) { fillTemplate(); } }
最新发布
10-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值