Spire.PDF is a professional PDF library applied to creating, writing, editing, handling and reading PDF files without any external dependencies. Get free and professional technical support for Spire.PDF for .NET, Java, Android, C++, Python.

Mon Jul 14, 2025 7:19 pm

Code: Select all
  public void replaceText(PdfDocument document, Map<String, String> replaceMap) {

        PdfPageCollection pages = document.getPages();
        replaceMap.forEach((key, value) -> {
            for (int i = 0; i < pages.getCount(); i++) {

                PdfPageBase page = pages.get(i);
                PdfTextFindCollection textFindCollection = page.findText(key, true, false);
                PdfTextFind[] finds = textFindCollection.getFinds();
                if (finds.length > 0) {
                    try {
                        finds[0].applyRecoverString(value);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
    }

    public static void main(String[] args) throws IOException {

        spirePdfUtils.replaceText(pdfDocument, Map.of("grade", "222"));
    }



报错有两个:
第一:
Exception in thread "main" com.spire.office.packages.sprwala: Neutral cultures cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture
at com.spire.office.packages.sprozja.spr©┦—(trf:234)
at com.spire.pdf.PdfPageBase.findText(Unknown Source)
at com.spire.pdf.PdfPageBase.findText(Unknown Source)

第二:
2025-07-15 03:02:56 |ERROR |https-jsse-nio-8089-exec-10 |DirectJDKLog.java:175 |org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] |Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.RuntimeException: class com.spire.office.packages.sprdraa: Fail to save. Saving of requested font type is not supported.
com.spire.office.packages.sprtlaa.spr▓⌮—(Unknown Source)
com.spire.pdf.graphics.PdfTrueTypeFont.<init>(Unknown Source)
com.spire.pdf.graphics.PdfTrueTypeFont.<init>(Unknown Source)
com.spire.pdf.graphics.PdfTrueTypeFont.<init>(Unknown Source)
com.spire.pdf.graphics.PdfTrueTypeFont.<init>(Unknown Source)
com.spire.pdf.general.find.PdfTextFind.spr┊┍—(Unknown Source)
com.spire.pdf.general.find.PdfTextFind.applyRecoverString(Unknown Source)

如何才能解决?

PiZhai09
 
Posts: 13
Joined: Mon Jul 14, 2025 7:14 pm

Tue Jul 15, 2025 2:39 am

helloooooooo?!

PiZhai09
 
Posts: 13
Joined: Mon Jul 14, 2025 7:14 pm

Tue Jul 15, 2025 2:57 am

您好,

感谢您的询问。

很抱歉,基于您目前提供的信息我无法复现出您遇到的问题。目前我们的Spire.PDF for Java最新版本为11.7.0,建议您更新到最新版本再进行测试。需要注意的是findText()方法在新版本的 Spire.Pdf for Java 中被废弃,您可以参考以下链接在最新版本中使用新方法进行查找替换操作:
https://www.e-iceblue.cn/pdf_java_text/find-and-replace-text-in-pdf-using-java.html

如果您使用最新版该问题依然存在,您可以将您出现该问题的文件发给我们吗?这将帮助我们进行进一步的调查并为您提供合适的解决方案。您可以将文件附在论坛上或者发送到邮箱:[email protected]。

期待您的测试反馈。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Tue Jul 15, 2025 3:25 am

感谢,我尝试了,可以实现文本的替换。
但是会导致pdf页面内容移动,我也知道这是真正实现文本替换的正常结果。
我想知道我要如何实现替换文本而不影响其他内容的位置。
比如:
1. 获取要被替换的文本的位置和长宽;
2. 将要被替换的文本遮盖;
3. 写入新文本;

PiZhai09
 
Posts: 13
Joined: Mon Jul 14, 2025 7:14 pm

Tue Jul 15, 2025 7:55 am

您好,

感谢您的测试反馈。

您可以使用以下代码来实现您希望的文本替换效果,使用该方法基本不会影响pdf原有的页面布局:

Code: Select all
       PdfDocument doc = new PdfDocument();

       doc.loadFromFile("Text.pdf");
       StringBuilder builder = new StringBuilder();
       for (Object pageBase : doc.getPages()) {
           PdfPageBase pagebase = (PdfPageBase) pageBase;
           PdfTextFinder find = new PdfTextFinder(pagebase);
           find.getOptions().setTextFindParameter(EnumSet.of(TextFindParameter.WholeWord));
           String text="PDF";
           List<PdfTextFragment> collection =find.find(text);
//           1. 获取要被替换的文本的位置和长宽;
           for (PdfTextFragment  fragment : collection) {

               Point2D[] locations = fragment.getPositions();
               Dimension2D[] size = fragment.getSizes();
               for (int i = 0; i < locations.length; i++) {
                   float x = (float) locations[i].getX();
                   float y = (float) locations[i].getY();
                   float h = (float) size[i].getHeight();
                   float w = (float) size[i].getWidth();
                   System.out.println("文本:"+text +"  X: " + x + " Y: " + y +"   height: " +h+"  width: "+w);

//                  2. 将要被替换的文本遮盖;
                   float width = h;
                   float height = w;
                   PdfPen pen = new PdfPen(new PdfRGBColor(Color.white), 0f);
                   PdfBrush brush=  PdfBrushes.getWhite();

                   pagebase.getCanvas().drawRectangle(pen, brush,x, y,height , width);

//                   3. 写入新文本;
                   String replacementText = "[test]";
                   PdfBrush textBrush = PdfBrushes.getBlack();
                   PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 12f );
                   float textWidth = (float) font.measureString(replacementText).getWidth();
                   pagebase.getCanvas().drawString(replacementText, font, textBrush, x, y);

               }
           }
           doc.saveToFile("replace.pdf");

如果您遇到任何问题,请随时与我们联系。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Tue Jul 15, 2025 2:03 pm

感谢您的回复。
我还有一个问题,发现使用下面的代码之后,在Linux centos8系统中会导致文件无法保存:
Code: Select all
    public void replaceText(PdfDocument document, Map<String, String> replaceMap) {

        PdfTextReplaceOptions textReplaceOptions = new PdfTextReplaceOptions();

        textReplaceOptions.setReplaceType(EnumSet.of(ReplaceActionType.IgnoreCase, ReplaceActionType.WholeWord));

        PdfPageCollection pages = document.getPages();
        replaceMap.forEach((key, value) -> {
            for (int i = 0; i < pages.getCount(); i++) {
                PdfPageBase page = pages.get(i);

                PdfTextReplacer textReplacer = new PdfTextReplacer(page);

                textReplacer.setOptions(textReplaceOptions);

                textReplacer.replaceAllText(key, value);
            }
        });
    }

报错:
Code: Select all
class com.spire.pdf.packages.sprvtu: The stream doesn't support reading.
com.spire.pdf.packages.sprcog.<init>(BinaryReader.java:43)
com.spire.pdf.packages.sprkxe.spr═⌫(Unknown Source)
com.spire.pdf.packages.sprkxe.spr┗⌬(Unknown Source)
com.spire.pdf.packages.sprkxe.spr⅛⌫(Unknown Source)
com.spire.pdf.packages.sprkxe.spr▃⌫(Unknown Source)
com.spire.pdf.packages.sprqbf.spr⅝∭(Unknown Source)
com.spire.pdf.packages.sprkwo.spr⅝∭(Unknown Source)
com.spire.pdf.packages.sprdcf.spr┾⌭(Unknown Source)
com.spire.pdf.packages.sprdcf.spr┶⌭(Unknown Source)
com.spire.pdf.packages.sprkgo.spr‘╽(Unknown Source)
com.spire.pdf.packages.sprkgo.spr◍╼(Unknown Source)
com.spire.pdf.packages.sprkgo.spr◍╻(Unknown Source)
com.spire.pdf.packages.sprkgo.spr⌫╼(Unknown Source)
com.spire.pdf.PdfNewDocument.spr▉¶(Unknown Source)
com.spire.pdf.PdfDocumentBase.save(Unknown Source)
com.spire.pdf.PdfDocumentBase.save(Unknown Source)
com.spire.pdf.PdfDocument.saveToFile(Unknown Source)

如果使用覆盖的方式,中文会乱码:
Code: Select all
    public void replaceTextByCover(PdfDocument doc, Map<String, String> replaceMap) {

        replaceMap.forEach((key, value) -> {
            for (Object pageBase : doc.getPages()) {
                PdfPageBase pagebase = (PdfPageBase) pageBase;
                PdfTextFinder find = new PdfTextFinder(pagebase);
                find.getOptions().setTextFindParameter(EnumSet.of(TextFindParameter.WholeWord));
                List<PdfTextFragment> collection = find.find(key);

                for (PdfTextFragment fragment : collection) {

                    Point2D[] locations = fragment.getPositions();
                    Dimension2D[] size = fragment.getSizes();
                    for (int i = 0; i < locations.length; i++) {
                        float x = (float) locations[i].getX();
                        float y = (float) locations[i].getY();
                        float h = (float) size[i].getHeight();
                        float w = (float) size[i].getWidth();

                        PdfPen pen = new PdfPen(new PdfRGBColor(Color.white), 0f);
                        PdfBrush brush = PdfBrushes.getWhite();

                        pagebase.getCanvas().drawRectangle(pen, brush, x, y, w, h);

                        PdfBrush textBrush = PdfBrushes.getBlack();
                        PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 12f);
                        pagebase.getCanvas().drawString(value, font, textBrush, x, y);
                    }
                }
            }
        });
    }

PiZhai09
 
Posts: 13
Joined: Mon Jul 14, 2025 7:14 pm

Wed Jul 16, 2025 3:39 am

感谢您的询问。

我在 Linux CentOS系统环境下进行了测试,但未能复现您遇到的问题。

请将您遇到报错的输入文件附在论坛上或发送至邮箱:[email protected],我们将进一步调查并为您提供合适的解决方案。

您使用覆盖方法出现乱码的问题,与您设置的字体错误有关,您在
Code: Select all
PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 12f);
中使用的字体Helvetica不支持中文渲染,请您改为
Code: Select all
PdfTureTypeFont font=new PdfTureTypeFont (new Font("宋体",12f),true)
进行测试(其中宋体可替换为系统中安装的任意支持中文渲染的字体)。

期待您的反馈。
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Wed Jul 16, 2025 6:39 am

感谢。我升级了版本发现问题解决了。
但是,发现图片信息的类和替换图片的方法被标记为已弃用。
Code: Select all
PdfImageInfo[]  = PdfPageBase.getImagesInfo();

PdfPageBase.replaceImage(int,PdfImage);

有下面的教程吗?
第一:获取pdf页面中的图片信息;
第二:替换PDF页面中的图片;

祝好

PiZhai09
 
Posts: 13
Joined: Mon Jul 14, 2025 7:14 pm

Wed Jul 16, 2025 7:44 am

您好,

在新版本中我们对这两个接口进行了升级,请使用下面的代码:
Code: Select all
// 获取页面中的图片信息
PdfImageHelper imageHelper = new PdfImageHelper();
PdfImageInfo[] imageInfos = imageHelper.getImagesInfo(page);

// 替换页面中的图片
imageHelper.replaceImage(imageInfos[0], image);

我们官网也有更详细的指导说明:
https://www.e-iceblue.cn/pdf_java_image_shapes/add-image-in-pdf-file-using-java.html
Sincerely,
Talia
E-iceblue support team
User avatar

talia.liu
 
Posts: 341
Joined: Mon Apr 14, 2025 3:33 am

Return to Spire.PDF

cron