繁体   English   中英

使用 pdfclown 很少有搜索关键字未在中文/日文文档中突出显示

[英]Using pdfclown few search keywords are not highlighting in chinese/japanese documents

我面临一些搜索关键字在中文文档中没有突出显示的问题。由于机密问题,我没有提供实际的 pdf。 搜索关键字是1)或2)收入亿来源请找到我测试过的pdf文档路径,pdfpath 链接 和 ActualResult 链接。我已经在以下链接中发布了与此问题相关的内容,但在少数中文文档中,某些关键字没有正确突出显示。请提供您的输入以突出显示我提到的搜索关键字。

    import java.awt.Color;
    import java.awt.Desktop;
    import java.awt.geom.Rectangle2D;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.net.URL;
    import java.nio.charset.Charset;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    import java.io.BufferedInputStream;
    import java.io.File;
    import org.pdfclown.documents.Page;
    import org.pdfclown.documents.contents.ITextString;
    import org.pdfclown.documents.contents.TextChar;
    import org.pdfclown.documents.contents.colorSpaces.DeviceRGBColor;
    import org.pdfclown.documents.interaction.annotations.TextMarkup;
    import org.pdfclown.documents.interaction.annotations.TextMarkup.MarkupTypeEnum;

    import org.pdfclown.files.SerializationModeEnum;
    import org.pdfclown.util.math.Interval;
    import org.pdfclown.util.math.geom.Quad;
    import org.pdfclown.tools.TextExtractor;

    public class pdfclown2 {
        private static int count;

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

            highlight("ebook.pdf","C:\\Users\\Downloads\\6.pdf");
            System.out.println("OK");
        }
        private static void highlight(String inputPath, String outputPath) throws IOException {

            URL url = new URL(inputPath);
            InputStream in = new BufferedInputStream(url.openStream());
            org.pdfclown.files.File file = null;

            try {
                file = new org.pdfclown.files.File("C:\\Users\\Desktop\\pdf\\test123.pdf");

            Map<String, String> m = new HashMap<String, String>();
                m.put("亿元或","hi");
                m.put("收入亿来","hi");



            System.out.println("map size"+m.size());
             long startTime = System.currentTimeMillis();




                // 2. Iterating through the document pages...
                TextExtractor textExtractor = new TextExtractor(true, true);
                for (final Page page : file.getDocument().getPages()) {
                    Map<Rectangle2D, List<ITextString>> textStrings = textExtractor.extract(page);
                    for (Map.Entry<String, String> entry : m.entrySet()) {

                        Pattern pattern;
                        String serachKey =  entry.getKey();
                        final String translationKeyword = entry.getValue();
                    /*
                            if ((serachKey.contains(")") && serachKey.contains("("))
                                    || (serachKey.contains("(") && !serachKey.contains(")"))
                                    || (serachKey.contains(")") && !serachKey.contains("(")) || serachKey.contains("?")
                                    || serachKey.contains("*") || serachKey.contains("+")) {s
                                pattern = Pattern.compile(Pattern.quote(serachKey), Pattern.CASE_INSENSITIVE);
                            }
                            else*/
                                 pattern = Pattern.compile(serachKey, Pattern.CASE_INSENSITIVE);
                    // 2.1. Extract the page text!

                //System.out.println(textStrings.toString().indexOf(entry.getKey()));

                    // 2.2. Find the text pattern matches!
                    final Matcher matcher = pattern.matcher(TextExtractor.toString(textStrings));
                    // 2.3. Highlight the text pattern matches!
                    textExtractor.filter(textStrings, new TextExtractor.IIntervalFilter() {
                        public boolean hasNext() {
                            // System.out.println(matcher.find());
                            // if(key.getMatchCriteria() == 1){
                            if (matcher.find()) {
                                return true;
                            }
                            /*
                             * } else if(key.getMatchCriteria() == 2) { if
                             * (matcher.hitEnd()) { count++; return true; } }
                             */
                            return false;

                        }

                        public Interval<Integer> next() {
                            return new Interval<Integer>(matcher.start(), matcher.end());
                        }

                        public void process(Interval<Integer> interval, ITextString match) {
                            // Defining the highlight box of the text pattern
                            // match...
                            System.out.println(match);
                        /*  List<Quad> highlightQuads = new ArrayList<Quad>();
                            {
                                Rectangle2D textBox = null;
                                for (TextChar textChar : match.getTextChars()) {
                                    Rectangle2D textCharBox = textChar.getBox();
                                    if (textBox == null) {
                                        textBox = (Rectangle2D) textCharBox.clone();
                                    } else {
                                        if (textCharBox.getY() > textBox.getMaxY()) {
                                            highlightQuads.add(Quad.get(textBox));
                                            textBox = (Rectangle2D) textCharBox.clone();
                                        } else {
                                            textBox.add(textCharBox);
                                        }
                                    }
                                }
                                textBox.setRect(textBox.getX(), textBox.getY(), textBox.getWidth(), textBox.getHeight());
                                highlightQuads.add(Quad.get(textBox));
                            }*/
                            List<Quad> highlightQuads = new ArrayList<Quad>();
                            List<TextChar> textChars = match.getTextChars();
                            Rectangle2D firstRect = textChars.get(0).getBox();
                            Rectangle2D lastRect = textChars.get(textChars.size()-1).getBox();
                            Rectangle2D rect = firstRect.createUnion(lastRect);
                            highlightQuads.add(Quad.get(rect).get(rect));
                            // subtype can be Highlight, Underline, StrikeOut, Squiggly


                            new TextMarkup(page, highlightQuads, translationKeyword, MarkupTypeEnum.Highlight);

                        }

                        public void remove() {
                            throw new UnsupportedOperationException();
                        }

                    });
                }

            }

            SerializationModeEnum serializationMode = SerializationModeEnum.Standard;

                file.save(new java.io.File(outputPath), serializationMode);

                System.out.println("file created");
                long endTime = System.currentTimeMillis();

                 System.out.println("seconds take for execution is:"+(endTime-startTime)/1000);

            } catch (Exception e) {
                   e.printStackTrace();
            }
            finally{
                in.close();
            }


        }
    }

确实,在搜索“$或”时,结果highlight有点错误:

错误截图

原因是 PDF Clown 错误。 当它解析复合字体(又名 Type 0 字体)时,它需要 Type 0 字体基本字典中的DW (默认宽度)条目,而它被指定在 CIDFont 子字典中!

对于手头的文档,大多数字符的宽度,尤其是中文字符,没有明确给出,因此默认为该DW值。 由于上述错误无法正确确定此值,因此使用了明确给定宽度的平均值,而该平均值恰好仅为正确值的 3/4。 因此,突出显示的区域太短。

您可以在方法onLoad的末尾修复CompositeFont类(包org.pdfclown.documents.contents.fonts )中的此错误。 只需更换

PdfInteger defaultWidthObject = (PdfInteger)getBaseDataObject().get(PdfName.DW);

经过

PdfInteger defaultWidthObject = (PdfInteger)getCIDFontDictionary().get(PdfName.DW);

突出显示现在导致

屏幕截图修复

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM