| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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.apache.poi.xwpf.usermodel; |
| |
| import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.poi.POIXMLDocumentPart; |
| import org.apache.poi.POIXMLException; |
| import org.apache.poi.openxml4j.exceptions.OpenXML4JException; |
| import org.apache.poi.openxml4j.opc.PackagePart; |
| import org.apache.xmlbeans.XmlException; |
| import org.apache.xmlbeans.XmlOptions; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLanguage; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPrDefault; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrDefault; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles; |
| import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
|
|
|
| /**
|
| * Holds details of built-in, default and user styles, which
|
| * apply to tables / paragraphs / lists etc.
|
| * Text within one of those with custom stylings has the style
|
| * information stored in the {@link XWPFRun}
|
| */
|
| public class XWPFStyles extends POIXMLDocumentPart {
|
| private CTStyles ctStyles;
|
| private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();
|
|
|
| private XWPFLatentStyles latentStyles;
|
| private XWPFDefaultRunStyle defaultRunStyle;
|
| private XWPFDefaultParagraphStyle defaultParaStyle;
|
| |
| /** |
| * Construct XWPFStyles from a package part |
| * |
| * @param part the package part holding the data of the styles, |
| * |
| * @since POI 3.14-Beta1 |
| */ |
| public XWPFStyles(PackagePart part) throws IOException, OpenXML4JException { |
| super(part); |
| } |
| |
| /** |
| * Construct XWPFStyles from scratch for a new document. |
| */ |
| public XWPFStyles() { |
| } |
| |
| /** |
| * Read document
|
| */
|
| @Override |
| protected void onDocumentRead() throws IOException { |
| StylesDocument stylesDoc; |
| InputStream is = getPackagePart().getInputStream(); |
| try { |
| stylesDoc = StylesDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); |
| setStyles(stylesDoc.getStyles()); |
| latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this); |
| } catch (XmlException e) { |
| throw new POIXMLException("Unable to read styles", e); |
| } finally { |
| is.close(); |
| } |
| } |
| |
| @Override |
| protected void commit() throws IOException { |
| if (ctStyles == null) { |
| throw new IllegalStateException("Unable to write out styles that were never read in!"); |
| } |
|
|
| XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
| xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
|
| PackagePart part = getPackagePart(); |
| OutputStream out = part.getOutputStream(); |
| ctStyles.save(out, xmlOptions); |
| out.close(); |
| }
|
|
|
| protected void ensureDocDefaults() {
|
| if (!ctStyles.isSetDocDefaults()) {
|
| ctStyles.addNewDocDefaults();
|
| }
|
|
|
| CTDocDefaults docDefaults = ctStyles.getDocDefaults();
|
| if (!docDefaults.isSetPPrDefault())
|
| docDefaults.addNewPPrDefault();
|
| if (!docDefaults.isSetRPrDefault())
|
| docDefaults.addNewRPrDefault();
|
|
|
| CTPPrDefault pprd = docDefaults.getPPrDefault();
|
| CTRPrDefault rprd = docDefaults.getRPrDefault();
|
| if (!pprd.isSetPPr()) pprd.addNewPPr();
|
| if (!rprd.isSetRPr()) rprd.addNewRPr();
|
|
|
| defaultRunStyle = new XWPFDefaultRunStyle(rprd.getRPr());
|
| defaultParaStyle = new XWPFDefaultParagraphStyle(pprd.getPPr());
|
| }
|
|
|
| /**
|
| * Sets the ctStyles
|
| *
|
| * @param styles
|
| */
|
| public void setStyles(CTStyles styles) { |
| ctStyles = styles;
|
|
|
| // Build up all the style objects
|
| for (CTStyle style : ctStyles.getStyleArray()) {
|
| listStyle.add(new XWPFStyle(style, this));
|
| }
|
| if (ctStyles.isSetDocDefaults()) {
|
| CTDocDefaults docDefaults = ctStyles.getDocDefaults(); |
| if (docDefaults.isSetRPrDefault() && docDefaults.getRPrDefault().isSetRPr()) { |
| defaultRunStyle = new XWPFDefaultRunStyle( |
| docDefaults.getRPrDefault().getRPr()); |
| } |
| if (docDefaults.isSetPPrDefault() && docDefaults.getPPrDefault().isSetPPr()) { |
| defaultParaStyle = new XWPFDefaultParagraphStyle( |
| docDefaults.getPPrDefault().getPPr()); |
| } |
| } |
| } |
|
|
| /**
|
| * checks whether style with styleID exist
|
| *
|
| * @param styleID styleID of the Style in the style-Document
|
| * @return true if style exist, false if style not exist
|
| */
|
| public boolean styleExist(String styleID) {
|
| for (XWPFStyle style : listStyle) {
|
| if (style.getStyleId().equals(styleID))
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| /**
|
| * add a style to the document
|
| *
|
| * @param style
|
| * @throws IOException
|
| */
|
| public void addStyle(XWPFStyle style) {
|
| listStyle.add(style);
|
| ctStyles.addNewStyle();
|
| int pos = ctStyles.sizeOfStyleArray() - 1;
|
| ctStyles.setStyleArray(pos, style.getCTStyle());
|
| }
|
|
|
| /**
|
| * Get style by a styleID
|
| *
|
| * @param styleID styleID of the searched style
|
| * @return style
|
| */
|
| public XWPFStyle getStyle(String styleID) {
|
| for (XWPFStyle style : listStyle) { |
| try { |
| if (style.getStyleId().equals(styleID)) |
| return style; |
| } catch (NullPointerException e) { |
| // Ignore NPE |
| } |
| }
|
| return null;
|
| }
|
|
|
| public int getNumberOfStyles() {
|
| return listStyle.size();
|
| }
|
|
|
| /**
|
| * get the styles which are related to the parameter style and their relatives
|
| * this method can be used to copy all styles from one document to another document
|
| *
|
| * @param style
|
| * @return a list of all styles which were used by this method
|
| */
|
| public List<XWPFStyle> getUsedStyleList(XWPFStyle style) {
|
| List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();
|
| usedStyleList.add(style);
|
| return getUsedStyleList(style, usedStyleList);
|
| }
|
|
|
| /**
|
| * get the styles which are related to parameter style
|
| *
|
| * @param style
|
| * @return all Styles of the parameterList
|
| */
|
| private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList) {
|
| String basisStyleID = style.getBasisStyleID();
|
| XWPFStyle basisStyle = getStyle(basisStyleID);
|
| if ((basisStyle != null) && (!usedStyleList.contains(basisStyle))) {
|
| usedStyleList.add(basisStyle);
|
| getUsedStyleList(basisStyle, usedStyleList);
|
| }
|
| String linkStyleID = style.getLinkStyleID();
|
| XWPFStyle linkStyle = getStyle(linkStyleID);
|
| if ((linkStyle != null) && (!usedStyleList.contains(linkStyle))) {
|
| usedStyleList.add(linkStyle);
|
| getUsedStyleList(linkStyle, usedStyleList);
|
| }
|
|
|
| String nextStyleID = style.getNextStyleID();
|
| XWPFStyle nextStyle = getStyle(nextStyleID);
|
| if ((nextStyle != null) && (!usedStyleList.contains(nextStyle))) {
|
| usedStyleList.add(linkStyle);
|
| getUsedStyleList(linkStyle, usedStyleList);
|
| }
|
| return usedStyleList;
|
| }
|
|
|
| protected CTLanguage getCTLanguage() {
|
| ensureDocDefaults();
|
|
|
| CTLanguage lang = null;
|
| if (defaultRunStyle.getRPr().isSetLang()) {
|
| lang = defaultRunStyle.getRPr().getLang();
|
| } else {
|
| lang = defaultRunStyle.getRPr().addNewLang();
|
| }
|
|
|
| return lang;
|
| }
|
|
|
| /**
|
| * Sets the default spelling language on ctStyles DocDefaults parameter
|
| *
|
| * @param strSpellingLanguage
|
| */
|
| public void setSpellingLanguage(String strSpellingLanguage) {
|
| CTLanguage lang = getCTLanguage(); |
| lang.setVal(strSpellingLanguage);
|
| lang.setBidi(strSpellingLanguage);
|
| }
|
|
|
| /**
|
| * Sets the default East Asia spelling language on ctStyles DocDefaults parameter
|
| *
|
| * @param strEastAsia
|
| */
|
| public void setEastAsia(String strEastAsia) {
|
| CTLanguage lang = getCTLanguage(); |
| lang.setEastAsia(strEastAsia); |
| } |
| |
| /**
|
| * Sets the default font on ctStyles DocDefaults parameter
|
| * TODO Replace this with specific setters for each type, possibly
|
| * on XWPFDefaultRunStyle
|
| */
|
| public void setDefaultFonts(CTFonts fonts) {
|
| ensureDocDefaults();
|
|
|
| CTRPr runProps = defaultRunStyle.getRPr();
|
| runProps.setRFonts(fonts);
|
| }
|
| |
| /** |
| * get the style with the same name
|
| * if this style is not existing, return null
|
| */
|
| public XWPFStyle getStyleWithSameName(XWPFStyle style) {
|
| for (XWPFStyle ownStyle : listStyle) {
|
| if (ownStyle.hasSameName(style)) {
|
| return ownStyle;
|
| }
|
| }
|
| return null;
|
| }
|
| |
| /** |
| * Get the default style which applies text runs in the document |
| */ |
| public XWPFDefaultRunStyle getDefaultRunStyle() { |
| ensureDocDefaults(); |
| return defaultRunStyle; |
| } |
| |
| /** |
| * Get the default paragraph style which applies to the document |
| */ |
| public XWPFDefaultParagraphStyle getDefaultParagraphStyle() { |
| ensureDocDefaults(); |
| return defaultParaStyle; |
| } |
| |
| /** |
| * Get the definition of all the Latent Styles |
| */ |
| public XWPFLatentStyles getLatentStyles() { |
| return latentStyles; |
| } |
| } |