Java itext从pdf文件中读取特定位置在intellij中运行,并提供所需的输出,但可执行jar抛出错误

Java itext从pdf文件中读取特定位置在intellij中运行,并提供所需的输出,但可执行jar抛出错误,java,intellij-idea,itext,executable-jar,Java,Intellij Idea,Itext,Executable Jar,我正在从一个有n个页面的输入pdf文件中读取特定位置,并列出这些位置上的文本列表。然后我编写一个新的pdf文档,并将列表中的字符串写入一个包含单元格的表中。我提出了两个主要问题 我希望表中有三列,但如果列表中的字符串不是3的倍数(即列数),则会留下额外的字符串,并且不会打印它们。例如,如果我有4个字符串要打印,那么程序将在第一行的三个单元格中打印前三个字符串,但会留下一个字符串。我编写了一些代码来检查字符串的数量,并将其mod(%)设为3,然后添加一些带有点(.)的空白单元格,以提供额外的单元格

我正在从一个有n个页面的输入pdf文件中读取特定位置,并列出这些位置上的文本列表。然后我编写一个新的pdf文档,并将列表中的字符串写入一个包含单元格的表中。我提出了两个主要问题

  • 我希望表中有三列,但如果列表中的字符串不是3的倍数(即列数),则会留下额外的字符串,并且不会打印它们。例如,如果我有4个字符串要打印,那么程序将在第一行的三个单元格中打印前三个字符串,但会留下一个字符串。我编写了一些代码来检查字符串的数量,并将其mod(
    %
    )设为3,然后添加一些带有点(.)的空白单元格,以提供额外的单元格来完成该行,这样就不会留下任何字符串。有更好的方法吗

  • 当我运行main类并为我生成输出pdf文件时,程序在intellij中运行。但是,当我创建可执行jar并双击运行它时,它什么也不做。为了再次检查,我在intellij终端中运行了jar,发现它抛出了以下错误:

  • 现在,当我在intellij中运行它时,为什么它没有给出相同的问题? 我如何克服这个问题? 我在Eclipse中重新编写了整个项目,Eclipse一点也不搞笑,并且给出了与intellij中的命令行上运行可执行文件相同的问题

    以下是我在项目中的三个课程:

    package addressLabels;
    
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.parser.FilteredTextRenderListener;
    import com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy;
    import com.itextpdf.text.pdf.parser.PdfTextExtractor;
    import com.itextpdf.text.pdf.parser.RegionTextRenderFilter;
    import com.itextpdf.text.pdf.parser.RenderFilter;
    import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Driver {
        public static final String SRC = "C:/temp/ebay.pdf";
    
        public static void main(String[] args) throws IOException, DocumentException {
            ReadCertainLocationOnPageInPdf contentsObj = new ReadCertainLocationOnPageInPdf(SRC);
            WritePdf writer = new WritePdf(contentsObj.getListOfAddresses());
            //contentsObj.printListOfAddresses();
        }
    
    }//class Driver ends here.
    
    package addressLabels;
    
    
    import com.itextpdf.text.Rectangle;
    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.parser.*;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class ReadCertainLocationOnPageInPdf {
    
        //private String cleanTextMarkedForTokenization;
        private List<String> listOfAddresses;
    
        public ReadCertainLocationOnPageInPdf(String pdfFileAddress){
            this.listOfAddresses = new ArrayList<String>();
            parsePdf(pdfFileAddress);
        }//constructor ends here.
    
        private void parsePdf(String pdfFileAddress) {
    
            File f = new File(pdfFileAddress);
            if (f.isFile() && f.canRead()){
                try {
                    PdfReader reader = new PdfReader(pdfFileAddress);
                    int numPages = reader.getNumberOfPages();
    
                    //Get information about the page size
                    //Rectangle mediabox = reader.getPageSize(1);
                    //printDataAboutThisPage(mediabox);
                    //StringBuilder sb = new StringBuilder("");
                    for (int pageNum = 1; pageNum <= numPages; pageNum++){
                        String oneAddress = getTextFromThisPage(pageNum, reader);
                        this.addOneAddressToListOfAddresses(oneAddress);
                        //sb.append(getTextFromThisPage(pageNum, reader)).append("\n\n");
                    }
                    //this.addOneAddressToListOfAddresses(sb.toString());
    
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }//if ends here
            //System.out.println(sb.toString());
        }
    
        private void printDataAboutThisPage(Rectangle mediabox) {
            //Lower left corner is x
            float x = mediabox.getRight();
            float y = mediabox.getTop();
            System.out.println("Lower left corner: " + x);
            System.out.println("Upper right conrner: " + y);
            System.out.println("The values of x increase from left to right; the values of y increase from bottom to top. \n The unit of the measurement system in PDF is called \"user unit\". \n By default one user unit coincides with one point (this can change, but you won't find many PDFs with a different UserUnit value).\n In normal circumstances, 72 user units = 1 inch.");
        }
    
        private String getTextFromThisPage(int pageNo, PdfReader reader) throws IOException {
            //java.awt.geom.Rectangle2D rect = new java.awt.geom.Rectangle2D.Float(226, 547, 240, 158);
            java.awt.geom.Rectangle2D rect = new java.awt.geom.Rectangle2D.Float(226, 547, 240, 158);
            RenderFilter regionFilter = new RegionTextRenderFilter(rect);
            TextExtractionStrategy strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), regionFilter);
            String t = PdfTextExtractor.getTextFromPage(reader, pageNo, strategy);
            t = this.cleanOneLabel(t);
            return t;
        }
    
        private String cleanOneLabel(String t) {
            StringBuilder sb2 = new StringBuilder("");
            String[] lines = t.split(System.getProperty("line.separator"));
            for(String s:lines) {
                if(!s.equals(""))
                    sb2.append(s).append("\n");
            }
            String pattern = "(?m)^\\s*\\r?\\n|\\r?\\n\\s*(?!.*\\r?\\n)";
            String replacement = "";
            return sb2.toString().replaceAll(pattern, replacement);// ??? s = s.replaceAll("\n+", "\n");
    
        }
        private String cleanOneLabel2(String t) {
            StringBuilder sb2 = new StringBuilder("");
            String[] lines = t.split(System.getProperty("line.separator"));
            for(int i = 0; i < lines.length; i++) {
                if(lines[i].contains("Post to:")) {
                    lines[i] = lines[i].replace("Post to:", "pakbay-Post to:");
                }
            }
            for(String s:lines) {
                if(!s.equals(""))
                    sb2.append(s).append("\n");
            }
            String pattern = "(?m)^\\s*\\r?\\n|\\r?\\n\\s*(?!.*\\r?\\n)";
            String replacement = "";
            return sb2.toString().replaceAll(pattern, replacement);// ??? s = s.replaceAll("\n+", "\n");
    
        }
    
        public List<String> getListOfAddresses(){
            return this.listOfAddresses;
        }
    
        public void printListOfAddresses(){
            for(int i = 0; i < listOfAddresses.size(); i++){
                System.out.print(listOfAddresses.get(i));
            }
        }
    
        public void addOneAddressToListOfAddresses(String oneAddress) {
            //clean the string before adding it to the list of addresses.
            //Remove extra spaces, tabs and blank lines from the passed string.
            String pattern = "(?m)^\\s*\\r?\\n|\\r?\\n\\s*(?!.*\\r?\\n)";
            String replacement = "";
            oneAddress = oneAddress.replaceAll(pattern, replacement);
            //Add the cleaned address to the list of addresses.
            this.listOfAddresses.add(oneAddress);
        }
    }//class ReadCertainLocationOnPageInPdf ends here.
    
    package addressLabels;
    
    import java.io.FileOutputStream;
    import java.util.Date;
    
    import com.itextpdf.text.*;
    import com.itextpdf.text.pdf.PdfPCell;
    import com.itextpdf.text.pdf.PdfPTable;
    import com.itextpdf.text.pdf.PdfWriter;
    
    public class WritePdf {
        private static String FILE = "C:/temp/ebay-output.pdf";
        private java.util.List<String> listOfAddresses;
    
    
        public WritePdf(java.util.List<String> listOfAddresses) {
            this.listOfAddresses = listOfAddresses;
            System.out.println("Size: " + this.getListOfAddresses().size());
            System.out.println("Element at zeroth position in list: " + this.getListOfAddresses().get(0));
            System.out.println("Element at nth position in list: " + this.getListOfAddresses().get(this.getListOfAddresses().size()-1));
            writeTheListOnPdf();
        }
    
        private void writeTheListOnPdf() {
            try {
                Document document = new Document();
                PdfWriter.getInstance(document, new FileOutputStream(FILE));
                document.open();
                addMetaData(document);
                //addTitlePage(document);
                addContent(document);
                document.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void addContent(Document document) throws DocumentException{
            PdfPTable table  = makeTable();
            for (int i = 0; i < this.getListOfAddresses().size() ; i++) {
                PdfPCell cell = makeCell();
                cell.addElement(new Phrase(this.getListOfAddresses().get(i)));
                table.addCell(cell);
            }
            /* we have three columns in the table. If the number of addresses is not exactly equal to the number of
             * cells created then the pdf file is corrupt and the program throws error. So we have to add some extra cells
             * to complete a row. */
            calculateAndAddExtraCells(table);
            document.add(table);
        }
    
        private void calculateAndAddExtraCells(PdfPTable table) {
    
            int numOfAddresses = this.getListOfAddresses().size();
            int numOfExtraCells = this.getListOfAddresses().size()%3;
            int loopCounter = 0;
    
            if (numOfExtraCells == 0)
                loopCounter = 3;
            else if (numOfExtraCells == 1)
                loopCounter = 2;
            else if (numOfExtraCells == 2)
                loopCounter = 1;
    
            for (int i = 1; i <= loopCounter ; i++) {
                PdfPCell blankCell = this.makeCell();
                blankCell.addElement(new Phrase("."));
                table.addCell(blankCell);
            }
        }
    
        private PdfPCell makeCell() {
            PdfPCell cell = new PdfPCell();
            cell.setPadding(4);
            //cell.setNoWrap(true);
            cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
            cell.setVerticalAlignment(PdfPCell.ALIGN_CENTER);
            cell.setBorder(Rectangle.NO_BORDER);
            return cell;
        }
    
        private PdfPTable makeTable() {
            PdfPTable table = new PdfPTable(3);
            table.setWidthPercentage(100);
            table.setSplitRows(false);
            return table;
        }
    
        private void addMetaData(Document document) {
            document.addTitle("Address labels for the input pdf file");
            document.addSubject("Address labels");
            document.addKeywords("ebay, amazon, addresses, labels");
            document.addAuthor("Ajmal Khan");
            document.addCreator("Ajmal Khan");
        }
    
        public java.util.List<String> getListOfAddresses() {
            return listOfAddresses;
        }
    
        public void setListOfAddresses(java.util.List<String> listOfAddresses) {
            this.listOfAddresses = listOfAddresses;
        }
    }//writePdf ends here.
    
    包裹地址标签;
    导入com.itextpdf.text.DocumentException;
    导入com.itextpdf.text.DocumentException;
    导入com.itextpdf.text.pdf.PdfReader;
    导入com.itextpdf.text.pdf.parser.FilteredTextRenderListener;
    导入com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy;
    导入com.itextpdf.text.pdf.parser.PdfTextExtractor;
    导入com.itextpdf.text.pdf.parser.RegionTextEnderFilter;
    导入com.itextpdf.text.pdf.parser.RenderFilter;
    导入com.itextpdf.text.pdf.parser.TextExtractionStrategy;
    导入java.io.File;
    导入java.io.IOException;
    导入java.util.ArrayList;
    导入java.util.List;
    公务舱司机{
    公共静态最终字符串SRC=“C:/temp/ebay.pdf”;
    公共静态void main(字符串[]args)引发IOException、DocumentException{
    ReadCertainLocationOnPageInPdf contentsAbj=新的ReadCertainLocationOnPageInPdf(SRC);
    WritePdf writer=newwritepDF(contentsObj.getListOfAddresses());
    //contentsObj.printlistofaddress();
    }
    }//类驱动程序到此结束。
    包装地址标签;
    导入com.itextpdf.text.Rectangle;
    导入com.itextpdf.text.pdf.PdfReader;
    导入com.itextpdf.text.pdf.parser.*;
    导入java.io.File;
    导入java.io.IOException;
    导入java.util.ArrayList;
    导入java.util.array;
    导入java.util.List;
    公共类ReadCertainLocationOnPageInPdf{
    //私有字符串cleanTextMarkedForTokenization;
    私人地址列表;
    public ReadCertainLocationOnPageInPdf(字符串PDFFiledAddress){
    this.listOfAddresses=新的ArrayList();
    PDF格式(PDF格式);
    }//构造函数到此结束。
    私有void解析PDF(字符串PDFFiledAddress){
    文件f=新文件(PDFFiledAddress);
    if(f.isFile()&&f.canRead()){
    试一试{
    PdfReader reader=新PdfReader(PDFFIEADREAD);
    int numPages=reader.getNumberOfPages();
    //获取有关页面大小的信息
    //矩形mediabox=reader.getPageSize(1);
    //打印有关此页的数据(mediabox);
    //StringBuilder sb=新的StringBuilder(“”);
    对于(int pageNum=1;pageNum)
    我希望表中有三列,但如果列表中的字符串不是3的倍数(即列数)然后它会留下额外的字符串并且不会打印它们。例如,如果我有4个字符串要打印,那么程序会在第一行的三个单元格中打印前三个字符串,但会留下一个字符串。我编写了一些代码来检查字符串的数量,并将其mod(%)改为3,并添加一些带点(.)的空白单元格在其中提供额外的单元格来完成行,这样就不会留下任何字符串。有更好的方法吗

    有一个
    PdfPTable
    方法为您填充最后一行:

    /**
     * Completes the current row with the default cell. An incomplete row will
     * be dropped but calling this method will make sure that it will be present
     * in the table.
     */
    public void completeRow()
    
    在将表添加到文档之前,只需调用此方法


    我在intellij终端中运行了jar,发现它抛出了以下错误

    NoSuchMethodError: com.itextpdf.text.pdf.parser.RegionTextRenderFilter.<init>(Ljava/awt/geom/Rectangle2D;)V
    
    NoSuchMethodError:com.itextpdf.text.pdf.parser.RegionTextRenderFilter.(Ljava/awt/geom/Rectangle2D;)V
    
    该错误是适当的,唯一接受
    Rectangle2D
    的iText5 RegionExtrenderFilter构造函数不需要
    java.awt.geom.Rectangle2D
    而是
    com.itextpdf.awt.geom.Rectangle2D

    因此,该程序在intellij中运行是令人惊讶的,而不是它在其他方面失败

    这可能是您不一致依赖关系的后续问题。正如@Amedee在评论中已经提到的:


    您正在混合不兼容版本的iText!
    iText xtra
    必须与
    itextpdf
    (最新发布版本:
    5.5.12
    )的版本相同,并且您的代码是典型的iText 5代码,因此您对iText 7的
    内核和
    布局模块的依赖性(最新发布版本:
    7.1.2
    )这是不需要的


    我找到了这两个问题的解决方案。对于创建安装程序的问题,我添加了以下依赖项以使其正常工作:

    <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>1.1</version>
    </dependency>
    
    
    公地郎
    公地郎
    2.1
    org.codehaus.plexus
    尾丛
    1.1
    
    我还删除了lib文件夹中的itextpdf jar文件
    <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>1.1</version>
    </dependency>
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <groupId>com.khanajmal</groupId>
    <artifactId>amazon</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <build>
        <plugins>
            <plugin>
    
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mianClass>addressLabels.Driver</mianClass>
                        </manifest>
                    </archive>
                </configuration>
    
            </plugin>
        </plugins>
    </build>
    
    <dependencies>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-utils</artifactId>
            <version>1.1</version>
        </dependency>
    
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.18</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-xtra -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-xtra</artifactId>
            <version>5.4.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.4</version>
        </dependency>
    
    </dependencies>
    
    table.completeRow();
        //When the method table.completeRow() inserts extra cells; they have borders. Removing them below.
        int lastRowIndex = table.getLastCompletedRowIndex();
        PdfPCell[] cells = table.getRow(lastRowIndex).getCells();
        for (int i = 0; i < cells.length; i++) {
            PdfPCell c = cells[i];
            c.setBorder(Rectangle.NO_BORDER);
        }
        //calculateAndAddExtraCells(table);
        document.add(table);