Remove duplicate footnote and reordering

Hi,

I use Aspose Word to generate a document via LINQ template. That document is very big (~30-200 pages). So, it has footnote inside and due to business case, 1 footnote number can be reference many times in the document.

So, the problem are:

  1. The footnotes are duplicated for one pages.
  2. The footnotes are not well ordering.

I tried to remove the redundant footnote by using this code but not work because after layout.getStartPageIndex is invoked, no change after will be applied to Document.

public static final void removeDuplicateFootnote(LayoutCollector layout, com.aspose.words.Document document,
DocumentBuilder builder) throws Exception {
NodeCollection<?> nodes = document.getChildNodes(NodeType.FOOTNOTE, true);
document.updatePageLayout();
// group footnote with its page.
Multimap<Integer, Footnote> footnotePageMap = ArrayListMultimap.create();
for(com.aspose.words.Node node : nodes.toArray()) {
Footnote footNote = (Footnote)node;
footnotePageMap.put(layout.getStartPageIndex(footNote), footNote);
}
// remove duplicate footnote
for (Entry<Integer, Collection> entry : footnotePageMap.asMap().entrySet()) {
final Multimap<String, Footnote> numberMap = ArrayListMultimap.create();
entry.getValue().forEach(e -> numberMap.put(e.getReferenceMark(), e));
for (Entry<String, Collection> nEntry : numberMap.asMap().entrySet()) {
if (nEntry.getValue().size() > 1) {// perform distinct modify number.
List footnotes = Lists.newArrayList(nEntry.getValue());
List removeOnes = footnotes.subList(1, footnotes.size());
for (Footnote removeOne : removeOnes) {
removeOne.remove();
}
}
}
}
}

Is it possible to solve above issues? I attached an example file output for your review.example.zip (15.1 KB)

Thanks and Best Regards,
Tu

@tranquoctu1988,

Thanks for your inquiry. In your case, we suggest you following solution.

  1. Get the collection of foot notes using Document.getChildNodes method.
  2. Store them into ArrayList.
  3. Remove the footnotes collection using Document.getChildNodes(NodeType.FOOTNOTE, true).clear().
  4. Move the cursor to the desired location and insert the footnote using DocumentBuilder.InsertFootnote method. Get the text from the ArrayList mention in step 2.

Hope this helps you. Please let us know if you have any more queries.

Thank for your quick response but your solution still not clear to me.
First, I want to

  1. Distinct footnote in one page.
  2. Reordering footnote in one pages.

But in your solution, step 3 will remove all the footnote in that page.

Remove the footnotes collection using Document.getChildNodes(NodeType.FOOTNOTE, true).clear().

and step 4

Move the cursor to the desired location and insert the footnote using DocumentBuilder.InsertFootnote method. Get the text from the ArrayList mention in step 2.

Because of step 3, there is no way to move cursor by using DocumentBuilder.moveTo, because this document is generated so, I can’t detect where will be the possible place for the footnote.

I expected the result will look like expected.zip (15.9 KB)

2 footnotes number 4 will be removed and the footnote in that page will become 1, 2, 4 instead of 4, 1, 2 ,4 ,4.

Thank you for considering my request.
Tu

@tranquoctu1988,

Thanks for your inquiry. Please use following code example to get the desired output. Hope this helps you.

Document document = new Document(MyDir + "example.docx");
DocumentBuilder builder = new DocumentBuilder(document);
NodeCollection<?> nodes = document.getChildNodes(NodeType.FOOTNOTE, true);
int i = 1;
ArrayList<String> fntext = new ArrayList<>();

for(com.aspose.words.Node node : nodes.toArray()) {
    Footnote footNote = (Footnote)node;
    builder.moveTo(node);
    builder.startBookmark("FootNote" + i);
    builder.endBookmark("FootNote" + i);
    i++;
    fntext.add(node.toString(SaveFormat.TEXT).replace("\r\n", ""));
}

document.updatePageLayout();
//Remove the Footnotes
document.getChildNodes(NodeType.FOOTNOTE, true).clear();

Set<String> uniqueList = new HashSet<String>(fntext);
java.util.List<String> footnotes = new ArrayList<String>(uniqueList);
Collections.sort(footnotes);
for (String text : footnotes)
{
    String[] marks = text.split(" ");
    Boolean moveto = builder.moveToBookmark("FootNote"+marks[0]);
    if(moveto)
    {
        builder.insertFootnote(FootnoteType.FOOTNOTE, text.substring(text.indexOf(" ")));
    }
}

document.getRange().getBookmarks().clear();
document.save(MyDir + "output.docx");

@tahir.manzoor

Thanks for your help. The propose solution is not satisfy our needs. It’s seem have the technical limitation.

In MS Words, when Footnote with reference mark 4 is insert before Footnote with reference mark 1 in one page, there is no way to order only in the footnote region that 1 will stay before 4.

Could you please confirm that we can or can’t order/distince only the value in footnote area and not change the footnote in that page?

So, if it can’t in the previous question. Do we have any way to do it in PDF version (because the final output is PDF)?
2017-09-27_1308_001.png (8.4 KB)

Thank you for considering my request.
Tu

@tranquoctu1988,

Thanks for your inquiry. Footnote is an inline-level node and can only be a child of Paragraph. Please note that Aspose.Words mimics the same behavior as MS Word does. You cannot order/distinct the value in footnote area. However, you can remove, modify, and insert the footnote. See the attached image for footnote. footnotes.png (16.0 KB)

If the solution shared in my previous post does not work for you, you may try following solution. Hope this helps you.

  1. Clone the Document using Document.Clone method.
  2. Remove footnotes from the original document.
  3. Get the footnotes form the clone document.
  4. Order and distinct them using Java code.
  5. Insert the footnotes into original document to desired location.