Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2013-2016, Plutext Pty Ltd.
*
* This file is part of docx4j.
docx4j is licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.docx4j.toc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.docx4j.Docx4J;
import org.docx4j.Docx4jProperties;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.out.ConversionFeatures;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.finders.SectPrFindFirst;
import org.docx4j.model.bookmarks.BookmarksIntegrity;
import org.docx4j.model.bookmarks.BookmarksIntegrity.BookmarksStatus;
import org.docx4j.model.listnumbering.Emulator;
import org.docx4j.model.listnumbering.Emulator.ResultTriple;
import org.docx4j.model.structure.PageDimensions;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.toc.switches.SwitchProcessor;
import org.docx4j.wml.Body;
import org.docx4j.wml.CTTabStop;
import org.docx4j.wml.Document;
import org.docx4j.wml.P;
import org.docx4j.wml.STTabTlc;
import org.docx4j.wml.SdtBlock;
import org.docx4j.wml.SdtContentBlock;
import org.docx4j.wml.SectPr;
import org.docx4j.wml.Tabs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class creates and populates a table of contents.
*
* If you want page numbers, getting this right (without opening
* the docx in Word to do so), is a challenge.
*
* This class supports generating the page numbers using
* export-fo (or the no-longer-available Converter).
*
* If you are using docx4j-export-documents4j-local|remote,
* you can use that for ToC generation.
*
* @author jharrop
*
*/
public class TocGenerator {
private static Logger log = LoggerFactory.getLogger(TocGenerator.class);
private WordprocessingMLPackage wordMLPackage;
public WordprocessingMLPackage getWordMLPackage() {
return wordMLPackage;
}
// boolean skipPageNumbering;
//
// public void setSkipPageNumbering(boolean skipPageNumbering) {
// this.skipPageNumbering = skipPageNumbering;
// }
/**
* From sectPr, we can get PageDimensions, which is used for
* calculating position of the right aligned tab for page numbers.
*/
private SectPr sectPr;
private TocGenerator() {}
// /**
// * @param docxFile
// * @throws TocException
// * @since 3.3.0
// */
// public TocGenerator(File docxFile) throws TocException {
//
// // The problem with this, is how do you get your result back out?
//
// try {
// wordMLPackage = WordprocessingMLPackage.load(docxFile);
// } catch (Docx4JException e) {
// throw new TocException(e.getMessage(),e);
// }
// this.tocStyles = getTocStyles(wordMLPackage.getMainDocumentPart());
// }
public TocGenerator(WordprocessingMLPackage wordMLPackage) throws TocException {
this.wordMLPackage = wordMLPackage;
this.tocStyles = TocStyles.getTocStyles(wordMLPackage.getMainDocumentPart());
}
private TocStyles tocStyles = null;
/**
* Generate Table of Contents using default TOC instruction, adding it at the beginning of the document
*
* To alter the ToC heading, use Toc.setTocHeadingText
*
* @param body of document
* @param skipPageNumbering don't generate page numbers (useful for HTML output, or speed, or as a fallback in case of issues)
* @return SdtBlock control
*/
@Deprecated
public static SdtBlock generateToc(WordprocessingMLPackage wordMLPackage, boolean skipPageNumbering) throws TocException {
return (new TocGenerator(wordMLPackage)).generateToc( 0, TocHelper.DEFAULT_TOC_INSTRUCTION, skipPageNumbering);
}
/**
* Generate Table of Contents using provided TOC instruction, adding at the given index in the body of document
*
* It is an error if a ToC content control is already present; delete it or use updateToc.
*
* To alter the ToC heading, use Toc.setTocHeadingText
*
* @param body
* @param index
* @param instruction
* @return SdtBlock control
*/
@Deprecated
public static SdtBlock generateToc(WordprocessingMLPackage wordMLPackage, int index, String instruction, boolean skipPageNumbering) throws TocException {
return (new TocGenerator(wordMLPackage)).generateToc( wordMLPackage, index, instruction, skipPageNumbering);
}
/**
* Generate Table of Contents using default TOC instruction, adding it at the beginning of the document
*
* To alter the ToC heading, use Toc.setTocHeadingText
*
* @param body of document
* @param skipPageNumbering don't generate page numbers (useful for HTML output, or speed, or as a fallback in case of issues)
* @return SdtBlock control
*/
public SdtBlock generateToc(boolean skipPageNumbering) throws TocException {
return generateToc( 0, TocHelper.DEFAULT_TOC_INSTRUCTION, skipPageNumbering);
}
/**
* Generate Table of Contents using provided TOC instruction, adding at the given index in the body of document,
* using dot leader for page numbering (if any).
*
* It is an error if a ToC content control is already present; delete it or use updateToc.
*
* To alter the ToC heading, use Toc.setTocHeadingText
*
* @param index
* @param instruction
* @param skipPageNumbering
* @return SdtBlock control
*/
public SdtBlock generateToc(int index, String instruction, boolean skipPageNumbering) throws TocException {
return generateToc( index, instruction, TocHelper.DEFAULT_TAB_LEADER, skipPageNumbering);
}
/**
* Generate Table of Contents using provided TOC instruction, and specified leader (eg dots) before
* page number, adding at the given index in the body of document
*
* It is an error if a ToC content control is already present; delete it or use updateToc.
*
* To alter the ToC heading, use Toc.setTocHeadingText
*
* @param index
* @param instruction
* @param leader
* @param skipPageNumbering
* @return SdtBlock control
* @since 3.3.2
*/
public SdtBlock generateToc(int index, String instruction, STTabTlc leader, boolean skipPageNumbering) throws TocException {
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
Document wmlDocumentEl = (Document)documentPart.getJaxbElement();
Body body = wmlDocumentEl.getBody();
TocFinder finder = new TocFinder();
new TraversalUtil(body.getContent(), finder);
SdtBlock sdt = finder.tocSDT;
if(sdt != null){
// OK
throw new TocException("ToC already present; use updateToc instead");
}
// Set sectPr, looking for it from index onwards
List