【问题标题】:remove extra blank lines删除多余的空行
【发布时间】:2017-01-15 16:21:27
【问题描述】:

我在 java 中使用 itext API 来创建和打印 PDF 文档中的动态内容。

下面是我需要在PDF文档中添加的动态内容。

This is first line.
This is second line.

This is third printed line.

This is fourth printed line.

#ACC004342-123





More information:
This is fifth printed line.
#ACC004342-123

This is Sixth printed line.
Some information goes here.

在上面显示的示例文本中,它们是#ACC004342-123 和更多信息之间的差距:我需要删除的行。

    public static File createInformationPdf(final List<MyDocumentType> content) throws AccServiceException
    {
        Document document = null;
        FileOutputStream fos = null;

        try
        {
             final String prefix = "letter";
        final File myPDF = File.createTempFile(prefix, ".pdf");
        document = new Document(PageSize.LETTER);

        fos = new FileOutputStream(temporaryPDF);

        PdfWriter.getInstance(document, fos);
        document.open();

        Font font = new Font(Font.FontFamily.COURIER,10);
   for (final MyDocumentType myDocument : content)
        {
            if (myDocument.getDocumentines() != null)
            {
                final DocumentLinesType documentLines = myDocument.getDocumentLines();
                for (final String line : documentLines.getDocumentLine())
                {
          document.add(new Paragraph(line,font));
                }
            }
  }
            document.close();
            return temporaryPDF;
        }
        catch (Exception e)
        {
         //log the exception
        }

    }

PS:上面是我的java代码,我只想删除#ACC004342-123和更多信息之间存在的更多空白行:行,然后在它们之间留一个空行.当我从 web 服务调用中获取该内容时,我需要在我的 java 代码中处理。希望我现在很清楚。谢谢。

【问题讨论】:

  • 这比你上一个问题的描述更好。诚然:您现在承认自己是一个肮脏的编码员,但至少现在我们可以帮助您并解释您做错了什么。我们现在了解导致不需要的空白行的原因。

标签: java pdf itext


【解决方案1】:

我已阅读您对我之前回答的评论:

我只想删除#ACC004342-123 和更多信息之间的多余空行:PDF 中的声明和打印。在我的代码中,我使用了 document.add(new Paragraph(" "));只给一个空行一次..由于内容是动态的,正如我所说,我们在 ACC 和更多信息之间获得了那些额外的空白行:我们需要在我们身边处理的行,删除那些额外的行(在 ACC 和更多信息:语句)并在 PDF 中打印,但我不想删除其他行之间的所有空白行。

也许您的问题的答案很简单。也许你把问题弄得太复杂了。

您如何看待这种方法:

final DocumentLinesType documentLines = myDocument.getDocumentLines();
List<String> lines = documentLines.getDocumentLine();
String line;
for (int i = 0; i < lines.size(); ) {
    line = lines.get(i);
    document.add(new Paragraph(12, lines.get(i), font));
    i++;
    if (line.contains("#ACC")) {
        while (lines.get(i).isEmpty())
            i++;
    }
}

我假设getSingleLine() 方法返回某种列表。我不知道,但既然你使用for (final String singleLine : myDocument.getSingleLine()),这是一个合理的假设。

一旦遇到包含“#ACC”的行,就会跳过所有空行,直到遇到非空行。现在您不必删除任何空白行,它们都会被跳过。

更新:

如果您想证明您的问题不是 iText 问题,请尝试此示例:

public static void main(String[] args) {
    List<String> lines = new ArrayList<String>();
    lines.add("This is first line.");
    lines.add("This is second line.");
    lines.add("");
    lines.add("This is third printed line.");
    lines.add("");
    lines.add("This is fourth printed line.");
    lines.add("");
    lines.add("#ACC004342-123");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("More information:");
    lines.add("This is fifth printed line.");
    lines.add("#ACC004342-123");
    lines.add("");
    lines.add("This is Sixth printed line.");
    lines.add("Some information goes here.");

    String line;
    for (int i = 0; i < lines.size(); ) {
        line = lines.get(i++);
        System.out.println(line);
        if (line.contains("#ACC")) {
            while (lines.get(i).isEmpty()) i++;
        }
    }
}

这段代码的输出如下所示:

This is first line.
This is second line.

This is third printed line.

This is fourth printed line.

#ACC004342-123
More information:
This is fifth printed line.
#ACC004342-123
This is Sixth printed line.
Some information goes here.

现在包含“#ACC#”的行之后不再有任何空行,但所有其他空行都被保留了。

如果要保留“#ACC”行之后的所有空白行,以防没有“更多信息行:”,则需要进行小幅调整:

public static void main(String[] args) {
    List<String> lines = new ArrayList<String>();
    lines.add("This is first line.");
    lines.add("This is second line.");
    lines.add("");
    lines.add("This is third printed line.");
    lines.add("");
    lines.add("This is fourth printed line.");
    lines.add("");
    lines.add("#ACC004342-123");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("");
    lines.add("More information:");
    lines.add("This is fifth printed line.");
    lines.add("#ACC004342-123");
    lines.add("");
    lines.add("This is Sixth printed line.");
    lines.add("Some information goes here.");

    String line;
    for (int i = 0; i < lines.size(); ) {
        line = lines.get(i++);
        System.out.println(line);
        int j = i;
        if (line.contains("#ACC")) {
            while (lines.get(j).isEmpty()) j++;
            if (lines.get(j).contains("More information"))
                i = j;
        }
    }
}

现在输出如下所示:

This is first line.
This is second line.

This is third printed line.

This is fourth printed line.

#ACC004342-123
More information:
This is fifth printed line.
#ACC004342-123

This is Sixth printed line.
Some information goes here.

【讨论】:

  • 请查看我的原始代码已编辑并添加到我上面的问题中。现在我很困惑如何将您的代码放入我的代码中。您希望我删除每个循环的内部并尝试使用你的代码..抱歉问了太多问题..@Bruno Lowagie
  • 真正烦人的是你问错了问题。 content 是什么?它是DocumentTypeList 吗? DocumentTypeDocumentLinesType 是什么? getDocumentLine() 返回什么?是List&lt;String&gt; 吗?你听起来像是一个试图激起 Stack Overflow 用户愤怒反应的巨魔。你为什么称自​​己为 javaUser?
  • 我很抱歉给您带来麻烦..可能是我无法表达我真正想要的..因为我从网络服务获取内容并且我认为我应该让问题更容易这就是没有添加的原因所有返回类型..为简单起见,请查看我编辑的 java 代码,并查看内容,我只是想删除#ACC 和更多信息之间存在的更多空白行:行..谢谢。 @Bruno Lowagie
  • 请看我编辑的帖子。希望现在很清楚。谢谢
  • 我已经更新了我的答案。如果这回答了您的问题,那么您已经浪费了很多时间:您的雇主的时间和我的时间一样。
【解决方案2】:

似乎每次添加包含#ACC 的行时,您都希望获得一些额外的空间。但是,根据您之前的问题limited content,我们也知道您希望避免在包含#ACC 的行是页面的最后一行时添加这个额外的空白。

您可以通过添加一个额外的Paragraph 来添加一个空行。这不是一个好主意,因为这意味着总是会添加一个空行,即使在您不想要的情况下也是如此。

最好使用setSpacingAfter() 方法。例如:

float spaceBetweenLines = 12;
Paragraph p;
for (final String singleLine : document.getSingleLine()) {
    p = new Paragraph(spaceBetweenLines, singleLine, font);
    if (singleLine.contains("#ACC")) {
        p.setSpacingAfter(spaceBetweenLines);
    }
    if (!singleLine().isEmpty())
        document.add(p);
}

此代码比您设置标志的代码更容易阅读和理解,原因是阅读您的代码的任何人(或必须维护您的代码)都很难理解。

实际上:仍然很难理解您的问题,因为您正在添加一个空行,同时要求删除一个空行。第三方很难理解您为什么要添加空白行。

使用setSpacingAfter() 这样的方法的美妙之处在于它只在必要时添加额外的空间。如果Paragraph 是文档的最后一段,则不添加空格。如果它是新页面之前的最后一段,则不添加空格(并且您在下一页上没有不必要的额外空间,这是您在上一个问题limited content 中描述的问题)。

或者我可能误解了这个问题。也许您想在段落之前添加一些额外的空格。在这种情况下,您可以使用setSpacingBefore() 方法:

float spaceBetweenLines = 12;
Paragraph p;
for (final String singleLine : document.getSingleLine()) {
    p = new Paragraph(spaceBetweenLines, singleLine, font);
    if (singleLine.contains("#ACC")) {
        p.setSpacingBefore(spaceBetweenLines);
    }
    if (!singleLine().isEmpty())
        document.add(p);
}

在这种情况下,在包含#ACC 的每一行之前添加额外的空格,除非该行是页面的第一行。在这种情况下,不会添加不需要的空白。

如果这不能回答您的问题,请重新表述您的问题。这已经比你之前的问题更清楚了,但是第三方仍然需要做很多猜测工作才能完全理解你在问什么。

【讨论】:

  • 我只想删除 #ACC004342-123 和更多信息之间的多余空行:报表并打印在 PDF 中。在我的代码中,我使用了 document.add(new Paragraph(" "));只给一个空行一次..由于内容是动态的,正如我所说,我们在 ACC 和更多信息之间获得了那些额外的空白行:我们需要在我们身边处理的行,删除那些额外的行(在 ACC 和更多信息:语句)并在 PDF 中打印,但我不想删除我在其他行之间的所有空白行。 @BrunoLowagie
  • 那么,如果我理解你的话,你希望“#ACC004342-123”和“更多信息:”在同一行吗?如果这不是正确的解释:需要删除哪些行?这些线是从哪里来的?如果您不想要它们,为什么要首先添加它们?你还是不清楚。
  • 请查看我的问题中显示的动态内容文本。我正在从 web 服务调用中获取该内容。如果您注意到“#ACC004342-123”和“更多信息:”它们之间的空行数量更多。我只想删除那些更多的空行,并在这两个语句之间留一个空行,剩余的内容应该按原样打印。只是想删除“#ACC004342-123”和“更多信息:”之间的那些额外的空白行。我不希望它们在同一行,只需删除更多的空白行。 @Bruno Lowagie。
  • 好的,我发布了另一个答案。您为什么将此标记为 iText 问题?你的问题在 Stack Overflow 上问起来太简单了。它与 iText 完全无关,但您的问题如此复杂以至于没人能回答。
【解决方案3】:

该标志使您的逻辑过于复杂,并且其用途尚不清楚。我认为下面的代码应该做你想做的。

if 语句检查它是否是“#ACC”行。如果是,则将文档传递给另一个方法,该方法会跳过所有空行并返回第一个非空行。这是您案例中的“更多信息”行。

如果未找到“#ACC”行,则正常打印该行。

public void removeMultipleEmptyLines(Document document){
    for (final String singleLine : document.getSingleLine()) {
        if (singleLine.contains("#ACC")) {
            document.add(new Paragraph(" ")); //adding one blank line
            String nextNonEmptyLine = getNextNonEmptyLine(Document document);//this should return the information line
            document.add(new Paragraph(12, nextNonEmptyLine, font));
        }else{
            document.add(new Paragraph(12, singleLine, font));              
        }
    }
}

private String getNextNonEmptyLine(Document document) {
    String singleLine = document.getSingleLine();
    while(singleLine.trim().length() == 0){
        singleLine = document.getSingleLine();
    }
    return singleLine;
}

【讨论】:

  • getSingleLine() 不是 Document 形式的方法。它是我们的内部方法,不属于 Document 对象。 @ColonelCustard
  • 我认为 Document 是您自己的内部类,因为您没有指定,这就是您第一次发布问题时使用它的方式。
  • 是的,对此感到抱歉。现在我在帖子中清理了我的代码。如上所述,在不与 if(singleLine.contains("#ACC")) 或任何其他静态字符串等静态内容进行比较的情况下,我们是否可以盲目检查我们是否有超过 2 个空行,只需删除那些额外的空行。我只是注意到动态内容中有没有这些字符串的场景。它可以在每个打印行之间允许 2 个空白行,但不能超过。因为在我的动态内容中,有时需要允许段落之间有一个空行,有时有两个空行。@ColonelCustard
  • 很抱歉,您想确保如果任何一行之间有多个空行,则将其减少为一个?
  • 我得到的每个打印行之间可以有一个或两个空白行。如果您看到上面的帖子,我给出的内容,在 ACC 和更多信息行之间,有许多空白行我需要删除,并且将来当我从 web 服务调用中获取该内容时,任何地方都可能随机出现空白行。所以如果超过 2 个,我只想删除空行。而且我不想像我们之前所做的那样检查任何静态文本。我正在使用 java 5 版本进行开发。
猜你喜欢
  • 2011-05-24
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 2016-05-19
  • 2012-01-24
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多