@@ -18,7 +18,7 @@ | |||
<classpathentry kind="lib" path="lib/ant-1.9.4.jar"/> | |||
<classpathentry kind="lib" path="lib/ant-launcher-1.9.4.jar"/> | |||
<classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/> | |||
<classpathentry exported="true" kind="lib" path="ooxml-lib/xmlbeans-2.6.0.jar"/> | |||
<classpathentry exported="true" kind="lib" path="ooxml-lib/xmlbeans-2.6.0.jar" sourcepath="ooxml-lib/xmlbeans-2.6.0.jar"/> | |||
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/> | |||
<classpathentry kind="lib" path="lib/junit-4.12.jar"/> | |||
<classpathentry kind="lib" path="ooxml-lib/curvesapi-1.04.jar"/> |
@@ -22,7 +22,7 @@ package org.apache.poi.ss.usermodel; | |||
/** | |||
* Represents a description of a conditional formatting rule | |||
*/ | |||
public interface ConditionalFormattingRule { | |||
public interface ConditionalFormattingRule extends DifferentialStyleProvider { | |||
/** | |||
* Create a new border formatting structure if it does not exist, | |||
* otherwise just return existing object. |
@@ -0,0 +1,32 @@ | |||
package org.apache.poi.ss.usermodel; | |||
/** | |||
* Interface for classes providing differential style definitions, such as conditional format rules | |||
* and table/pivot table styles. | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public interface DifferentialStyleProvider { | |||
/** | |||
* @return - border formatting object if defined, <code>null</code> otherwise | |||
*/ | |||
BorderFormatting getBorderFormatting(); | |||
/** | |||
* @return - font formatting object if defined, <code>null</code> otherwise | |||
*/ | |||
FontFormatting getFontFormatting(); | |||
/** | |||
* | |||
* @return number format defined for this rule, or null if the cell default should be used | |||
*/ | |||
ExcelNumberFormat getNumberFormat(); | |||
/** | |||
* @return - pattern formatting object if defined, <code>null</code> otherwise | |||
*/ | |||
PatternFormatting getPatternFormatting(); | |||
} |
@@ -77,5 +77,9 @@ public interface Table { | |||
*/ | |||
boolean isHasTotalsRow(); | |||
/** | |||
* @return TableStyleInfo for this instance | |||
* @since 3.17 beta 1 | |||
*/ | |||
TableStyleInfo getStyle(); | |||
} |
@@ -0,0 +1,23 @@ | |||
package org.apache.poi.ss.usermodel; | |||
/** | |||
* Data table style definition. Includes style elements for various table components. | |||
* Any number of style elements may be represented, and any cell may be styled by | |||
* multiple elements. The order of elements in {@link TableStyleType} defines precedence. | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public interface TableStyle { | |||
/** | |||
* @return name (may be a builtin name) | |||
*/ | |||
String getName(); | |||
/** | |||
* | |||
* @param type | |||
* @return style definition for the given type, or null if not defined in this style. | |||
*/ | |||
DifferentialStyleProvider getStyle(TableStyleType type); | |||
} |
@@ -0,0 +1,40 @@ | |||
package org.apache.poi.ss.usermodel; | |||
/** | |||
* style information for a specific table instance, referencing the document style | |||
* and indicating which optional portions of the style to apply. | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public interface TableStyleInfo { | |||
/** | |||
* @return true if alternating column styles should be applied | |||
*/ | |||
boolean isShowColumnStripes(); | |||
/** | |||
* @return true if alternating row styles should be applied | |||
*/ | |||
boolean isShowRowStripes(); | |||
/** | |||
* @return true if the distinct first column style should be applied | |||
*/ | |||
boolean isShowFirstColumn(); | |||
/** | |||
* @return true if the distinct last column style should be applied | |||
*/ | |||
boolean isShowLastColumn(); | |||
/** | |||
* @return the name of the style (may reference a built-in style) | |||
*/ | |||
String getName(); | |||
/** | |||
* @return style definition | |||
*/ | |||
TableStyle getStyle(); | |||
} |
@@ -0,0 +1,49 @@ | |||
package org.apache.poi.ss.usermodel; | |||
/** | |||
* Ordered list of table style elements, for both data tables and pivot tables. | |||
* Some elements only apply to pivot tables, but any style definition can omit any number, | |||
* so having them in one list should not be a problem. | |||
* <p/> | |||
* The order is the specification order of application, with later elements overriding previous | |||
* ones, if style properties conflict. | |||
* <p/> | |||
* Processing could iterate bottom-up if looking for specific properties, and stop when the | |||
* first style is found defining a value for that property. | |||
* <p/> | |||
* Enum names match the OOXML spec values exactly, so {@link #valueOf(String)} will work. | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public enum TableStyleType { | |||
wholeTable, | |||
headerRow, | |||
totalRow, | |||
firstColumn, | |||
lastColumn, | |||
firstRowStripe, | |||
secondRowStripe, | |||
firstColumnStripe, | |||
secondColumnStripe, | |||
firstHeaderCell, | |||
lastHeaderCell, | |||
firstTotalCell, | |||
lastTotalCell, | |||
firstSubtotalColumn, | |||
secondSubtotalColumn, | |||
thirdSubtotalColumn, | |||
firstSubtotalRow, | |||
secondSubtotalRow, | |||
thirdSubtotalRow, | |||
blankRow, | |||
firstColumnSubheading, | |||
secondColumnSubheading, | |||
thirdColumnSubheading, | |||
firstRowSubheading, | |||
secondRowSubheading, | |||
thirdRowSubheading, | |||
pageFieldLabels, | |||
pageFieldValues, | |||
; | |||
} |
@@ -25,6 +25,7 @@ import java.io.OutputStream; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Map.Entry; | |||
@@ -37,11 +38,14 @@ import org.apache.poi.ss.SpreadsheetVersion; | |||
import org.apache.poi.ss.usermodel.BuiltinFormats; | |||
import org.apache.poi.ss.usermodel.FontFamily; | |||
import org.apache.poi.ss.usermodel.FontScheme; | |||
import org.apache.poi.ss.usermodel.TableStyle; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.xssf.usermodel.XSSFBuiltinTableStyle; | |||
import org.apache.poi.xssf.usermodel.XSSFCellStyle; | |||
import org.apache.poi.xssf.usermodel.XSSFFactory; | |||
import org.apache.poi.xssf.usermodel.XSSFFont; | |||
import org.apache.poi.xssf.usermodel.XSSFRelation; | |||
import org.apache.poi.xssf.usermodel.XSSFTableStyle; | |||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; | |||
import org.apache.poi.xssf.usermodel.extensions.XSSFCellFill; | |||
@@ -59,6 +63,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFonts; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmts; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTStylesheet; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyle; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyles; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPatternType; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.StyleSheetDocument; | |||
@@ -75,6 +81,7 @@ public class StylesTable extends POIXMLDocumentPart { | |||
private final List<CTXf> xfs = new ArrayList<CTXf>(); | |||
private final List<CTDxf> dxfs = new ArrayList<CTDxf>(); | |||
private final Map<String, TableStyle> tableStyles = new HashMap<String, TableStyle>(); | |||
/** | |||
* The first style id available for use as a custom style | |||
@@ -189,7 +196,7 @@ public class StylesTable extends POIXMLDocumentPart { | |||
* @param is The input stream containing the XML document. | |||
* @throws IOException if an error occurs while reading. | |||
*/ | |||
protected void readFrom(InputStream is) throws IOException { | |||
public void readFrom(InputStream is) throws IOException { | |||
try { | |||
doc = StyleSheetDocument.Factory.parse(is, DEFAULT_XML_OPTIONS); | |||
@@ -237,6 +244,13 @@ public class StylesTable extends POIXMLDocumentPart { | |||
CTDxfs styleDxfs = styleSheet.getDxfs(); | |||
if(styleDxfs != null) dxfs.addAll(Arrays.asList(styleDxfs.getDxfArray())); | |||
CTTableStyles ctTableStyles = styleSheet.getTableStyles(); | |||
if (ctTableStyles != null) { | |||
for (CTTableStyle style : Arrays.asList(ctTableStyles.getTableStyleArray())) { | |||
tableStyles.put(style.getName(), new XSSFTableStyle(styleDxfs, style)); | |||
} | |||
} | |||
} catch (XmlException e) { | |||
throw new IOException(e.getLocalizedMessage()); | |||
} | |||
@@ -766,7 +780,33 @@ public class StylesTable extends POIXMLDocumentPart { | |||
this.dxfs.add(dxf); | |||
return this.dxfs.size(); | |||
} | |||
/** | |||
* NOTE: this only returns explicitly defined styles | |||
* @param name of the table style | |||
* @return defined style, or null if not explicitly defined | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public TableStyle getExplicitTableStyle(String name) { | |||
return tableStyles.get(name); | |||
} | |||
/** | |||
* @param name of the table style | |||
* @return defined style, either explicit or built-in, or null if not found | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public TableStyle getTableStyle(String name) { | |||
if (name == null) return null; | |||
try { | |||
return XSSFBuiltinTableStyle.valueOf(name).getStyle(); | |||
} catch (IllegalArgumentException e) { | |||
return getExplicitTableStyle(name); | |||
} | |||
} | |||
/** | |||
* Create a cell style in this style table. | |||
* Note - End users probably want to call {@link XSSFWorkbook#createCellStyle()} |
@@ -0,0 +1,411 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.InputStream; | |||
import java.nio.charset.Charset; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.poi.ss.usermodel.TableStyle; | |||
import org.apache.poi.util.DocumentHelper; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.xssf.model.StylesTable; | |||
import org.apache.xmlbeans.XmlOptions; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxfs; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyle; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.Node; | |||
import org.w3c.dom.NodeList; | |||
import org.w3c.dom.ls.DOMImplementationLS; | |||
import org.w3c.dom.ls.LSSerializer; | |||
/** | |||
* Table style names defined in the OOXML spec. | |||
* The actual styling is defined in presetTableStyles.xml | |||
*/ | |||
public enum XSSFBuiltinTableStyle { | |||
/***/ | |||
TableStyleDark1, | |||
/***/ | |||
TableStyleDark2, | |||
/***/ | |||
TableStyleDark3, | |||
/***/ | |||
TableStyleDark4, | |||
/***/ | |||
TableStyleDark5, | |||
/***/ | |||
TableStyleDark6, | |||
/***/ | |||
TableStyleDark7, | |||
/***/ | |||
TableStyleDark8, | |||
/***/ | |||
TableStyleDark9, | |||
/***/ | |||
TableStyleDark10, | |||
/***/ | |||
TableStyleDark11, | |||
/***/ | |||
TableStyleLight1, | |||
/***/ | |||
TableStyleLight2, | |||
/***/ | |||
TableStyleLight3, | |||
/***/ | |||
TableStyleLight4, | |||
/***/ | |||
TableStyleLight5, | |||
/***/ | |||
TableStyleLight6, | |||
/***/ | |||
TableStyleLight7, | |||
/***/ | |||
TableStyleLight8, | |||
/***/ | |||
TableStyleLight9, | |||
/***/ | |||
TableStyleLight10, | |||
/***/ | |||
TableStyleLight11, | |||
/***/ | |||
TableStyleLight12, | |||
/***/ | |||
TableStyleLight13, | |||
/***/ | |||
TableStyleLight14, | |||
/***/ | |||
TableStyleLight15, | |||
/***/ | |||
TableStyleLight16, | |||
/***/ | |||
TableStyleLight17, | |||
/***/ | |||
TableStyleLight18, | |||
/***/ | |||
TableStyleLight19, | |||
/***/ | |||
TableStyleLight20, | |||
/***/ | |||
TableStyleLight21, | |||
/***/ | |||
TableStyleMedium1, | |||
/***/ | |||
TableStyleMedium2, | |||
/***/ | |||
TableStyleMedium3, | |||
/***/ | |||
TableStyleMedium4, | |||
/***/ | |||
TableStyleMedium5, | |||
/***/ | |||
TableStyleMedium6, | |||
/***/ | |||
TableStyleMedium7, | |||
/***/ | |||
TableStyleMedium8, | |||
/***/ | |||
TableStyleMedium9, | |||
/***/ | |||
TableStyleMedium10, | |||
/***/ | |||
TableStyleMedium11, | |||
/***/ | |||
TableStyleMedium12, | |||
/***/ | |||
TableStyleMedium13, | |||
/***/ | |||
TableStyleMedium14, | |||
/***/ | |||
TableStyleMedium15, | |||
/***/ | |||
TableStyleMedium16, | |||
/***/ | |||
TableStyleMedium17, | |||
/***/ | |||
TableStyleMedium18, | |||
/***/ | |||
TableStyleMedium19, | |||
/***/ | |||
TableStyleMedium20, | |||
/***/ | |||
TableStyleMedium21, | |||
/***/ | |||
TableStyleMedium22, | |||
/***/ | |||
TableStyleMedium23, | |||
/***/ | |||
TableStyleMedium24, | |||
/***/ | |||
TableStyleMedium25, | |||
/***/ | |||
TableStyleMedium26, | |||
/***/ | |||
TableStyleMedium27, | |||
/***/ | |||
TableStyleMedium28, | |||
/***/ | |||
PivotStyleMedium1, | |||
/***/ | |||
PivotStyleMedium2, | |||
/***/ | |||
PivotStyleMedium3, | |||
/***/ | |||
PivotStyleMedium4, | |||
/***/ | |||
PivotStyleMedium5, | |||
/***/ | |||
PivotStyleMedium6, | |||
/***/ | |||
PivotStyleMedium7, | |||
/***/ | |||
PivotStyleMedium8, | |||
/***/ | |||
PivotStyleMedium9, | |||
/***/ | |||
PivotStyleMedium10, | |||
/***/ | |||
PivotStyleMedium11, | |||
/***/ | |||
PivotStyleMedium12, | |||
/***/ | |||
PivotStyleMedium13, | |||
/***/ | |||
PivotStyleMedium14, | |||
/***/ | |||
PivotStyleMedium15, | |||
/***/ | |||
PivotStyleMedium16, | |||
/***/ | |||
PivotStyleMedium17, | |||
/***/ | |||
PivotStyleMedium18, | |||
/***/ | |||
PivotStyleMedium19, | |||
/***/ | |||
PivotStyleMedium20, | |||
/***/ | |||
PivotStyleMedium21, | |||
/***/ | |||
PivotStyleMedium22, | |||
/***/ | |||
PivotStyleMedium23, | |||
/***/ | |||
PivotStyleMedium24, | |||
/***/ | |||
PivotStyleMedium25, | |||
/***/ | |||
PivotStyleMedium26, | |||
/***/ | |||
PivotStyleMedium27, | |||
/***/ | |||
PivotStyleMedium28, | |||
/***/ | |||
PivotStyleLight1, | |||
/***/ | |||
PivotStyleLight2, | |||
/***/ | |||
PivotStyleLight3, | |||
/***/ | |||
PivotStyleLight4, | |||
/***/ | |||
PivotStyleLight5, | |||
/***/ | |||
PivotStyleLight6, | |||
/***/ | |||
PivotStyleLight7, | |||
/***/ | |||
PivotStyleLight8, | |||
/***/ | |||
PivotStyleLight9, | |||
/***/ | |||
PivotStyleLight10, | |||
/***/ | |||
PivotStyleLight11, | |||
/***/ | |||
PivotStyleLight12, | |||
/***/ | |||
PivotStyleLight13, | |||
/***/ | |||
PivotStyleLight14, | |||
/***/ | |||
PivotStyleLight15, | |||
/***/ | |||
PivotStyleLight16, | |||
/***/ | |||
PivotStyleLight17, | |||
/***/ | |||
PivotStyleLight18, | |||
/***/ | |||
PivotStyleLight19, | |||
/***/ | |||
PivotStyleLight20, | |||
/***/ | |||
PivotStyleLight21, | |||
/***/ | |||
PivotStyleLight22, | |||
/***/ | |||
PivotStyleLight23, | |||
/***/ | |||
PivotStyleLight24, | |||
/***/ | |||
PivotStyleLight25, | |||
/***/ | |||
PivotStyleLight26, | |||
/***/ | |||
PivotStyleLight27, | |||
/***/ | |||
PivotStyleLight28, | |||
/***/ | |||
PivotStyleDark1, | |||
/***/ | |||
PivotStyleDark2, | |||
/***/ | |||
PivotStyleDark3, | |||
/***/ | |||
PivotStyleDark4, | |||
/***/ | |||
PivotStyleDark5, | |||
/***/ | |||
PivotStyleDark6, | |||
/***/ | |||
PivotStyleDark7, | |||
/***/ | |||
PivotStyleDark8, | |||
/***/ | |||
PivotStyleDark9, | |||
/***/ | |||
PivotStyleDark10, | |||
/***/ | |||
PivotStyleDark11, | |||
/***/ | |||
PivotStyleDark12, | |||
/***/ | |||
PivotStyleDark13, | |||
/***/ | |||
PivotStyleDark14, | |||
/***/ | |||
PivotStyleDark15, | |||
/***/ | |||
PivotStyleDark16, | |||
/***/ | |||
PivotStyleDark17, | |||
/***/ | |||
PivotStyleDark18, | |||
/***/ | |||
PivotStyleDark19, | |||
/***/ | |||
PivotStyleDark20, | |||
/***/ | |||
PivotStyleDark21, | |||
/***/ | |||
PivotStyleDark22, | |||
/***/ | |||
PivotStyleDark23, | |||
/***/ | |||
PivotStyleDark24, | |||
/***/ | |||
PivotStyleDark25, | |||
/***/ | |||
PivotStyleDark26, | |||
/***/ | |||
PivotStyleDark27, | |||
/***/ | |||
PivotStyleDark28, | |||
; | |||
private static final Map<XSSFBuiltinTableStyle, TableStyle> styleMap = new HashMap<XSSFBuiltinTableStyle, TableStyle>(60); | |||
private XSSFBuiltinTableStyle() { | |||
} | |||
/** | |||
* @return built-in {@link TableStyle} definition | |||
*/ | |||
public TableStyle getStyle() { | |||
init(); | |||
return styleMap.get(this); | |||
} | |||
/** | |||
* NOTE: only checks by name, not definition. | |||
* @param style | |||
* @return true if the style represents a built-in style, false if it is null or a custom style | |||
*/ | |||
public static boolean isBuiltinStyle(TableStyle style) { | |||
if (style == null) return false; | |||
try { | |||
XSSFBuiltinTableStyle.valueOf(style.getName()); | |||
return true; | |||
} catch (IllegalArgumentException e) { | |||
return false; | |||
} | |||
} | |||
/** | |||
* Only init once - thus the synchronized. Lazy, after creating instances, | |||
* and only when a style is actually needed, to avoid overhead for uses | |||
* that don't need the actual style definitions. | |||
* <p/> | |||
* Public so clients can initialize the map on startup rather than lazily | |||
* during evaluation if desired. | |||
*/ | |||
public static final synchronized void init() { | |||
if (! styleMap.isEmpty()) return; | |||
/* | |||
* initialize map. Every built-in has this format: | |||
* <styleName> | |||
* <dxfs> | |||
* <dxf>...</dxf> | |||
* ... | |||
* </dxfs> | |||
* <tableStyles count="1"> | |||
* <tableStyle>...</tableStyle> | |||
* </tableStyles> | |||
* </styleName> | |||
*/ | |||
try { | |||
final InputStream is = XSSFBuiltinTableStyle.class.getResourceAsStream("presetTableStyles.xml"); | |||
try { | |||
final Document doc = DocumentHelper.readDocument(is); | |||
final NodeList styleNodes = doc.getDocumentElement().getChildNodes(); | |||
for (int i=0; i < styleNodes.getLength(); i++) { | |||
final Node node = styleNodes.item(i); | |||
if (node.getNodeType() != Node.ELEMENT_NODE) continue; // only care about elements | |||
final Element tag = (Element) node; | |||
String styleName = tag.getTagName(); | |||
Node dxfsNode = tag.getElementsByTagName("dxfs").item(0); | |||
Node tableStyleNode = tag.getElementsByTagName("tableStyles").item(0); | |||
// hack because I can't figure out how to get XMLBeans to parse a sub-element in a standalone manner | |||
// - build a fake styles.xml file with just this built-in | |||
StylesTable styles = new StylesTable(); | |||
styles.readFrom(new ByteArrayInputStream(styleXML(dxfsNode, tableStyleNode).getBytes(Charset.forName("UTF-8")))); | |||
styleMap.put(XSSFBuiltinTableStyle.valueOf(styleName), styles.getExplicitTableStyle(styleName)); | |||
} | |||
} finally { | |||
IOUtils.closeQuietly(is); | |||
} | |||
} catch (Exception e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
private static String styleXML(Node dxfsNode, Node tableStyleNode) { | |||
DOMImplementationLS lsImpl = (DOMImplementationLS)dxfsNode.getOwnerDocument().getImplementation().getFeature("LS", "3.0"); | |||
LSSerializer lsSerializer = lsImpl.createLSSerializer(); | |||
lsSerializer.getDomConfig().setParameter("xml-declaration", false); | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n") | |||
.append("<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" " | |||
+ "xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" " | |||
+ "xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" " | |||
+ "xmlns:x16r2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main\" " | |||
+ "mc:Ignorable=\"x14ac x16r2\">\n"); | |||
sb.append(lsSerializer.writeToString(dxfsNode)); | |||
sb.append(lsSerializer.writeToString(tableStyleNode)); | |||
sb.append("</styleSheet>"); | |||
return sb.toString(); | |||
} | |||
} |
@@ -0,0 +1,59 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.apache.poi.ss.usermodel.BorderFormatting; | |||
import org.apache.poi.ss.usermodel.DifferentialStyleProvider; | |||
import org.apache.poi.ss.usermodel.ExcelNumberFormat; | |||
import org.apache.poi.ss.usermodel.FontFormatting; | |||
import org.apache.poi.ss.usermodel.PatternFormatting; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt; | |||
/** | |||
* Style based on a dxf record - e.g. table style element or conditional formatting rule | |||
*/ | |||
public class XSSFDxfStyleProvider implements DifferentialStyleProvider { | |||
private final BorderFormatting border; | |||
private final FontFormatting font; | |||
private final ExcelNumberFormat number; | |||
private final PatternFormatting fill; | |||
/** | |||
* @param dxf | |||
*/ | |||
public XSSFDxfStyleProvider(CTDxf dxf) { | |||
if (dxf == null) { | |||
border = null; | |||
font = null; | |||
number = null; | |||
fill = null; | |||
} else { | |||
border = dxf.isSetBorder() ? new XSSFBorderFormatting(dxf.getBorder()) : null; | |||
font = dxf.isSetFont() ? new XSSFFontFormatting(dxf.getFont()) : null; | |||
if (dxf.isSetNumFmt()) { | |||
CTNumFmt numFmt = dxf.getNumFmt(); | |||
number = new ExcelNumberFormat((int) numFmt.getNumFmtId(), numFmt.getFormatCode()); | |||
} else { | |||
number = null; | |||
} | |||
fill = dxf.isSetFill() ? new XSSFPatternFormatting(dxf.getFill()) : null; | |||
} | |||
} | |||
public BorderFormatting getBorderFormatting() { | |||
return border; | |||
} | |||
public FontFormatting getFontFormatting() { | |||
return font; | |||
} | |||
public ExcelNumberFormat getNumberFormat() { | |||
return number; | |||
} | |||
public PatternFormatting getPatternFormatting() { | |||
return fill; | |||
} | |||
} |
@@ -31,6 +31,7 @@ import java.util.Locale; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.ss.usermodel.Table; | |||
import org.apache.poi.ss.usermodel.TableStyleInfo; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.StringUtil; | |||
@@ -444,4 +445,13 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { | |||
public int getEndRowIndex() { | |||
return getEndCellReference().getRow(); | |||
} | |||
/** | |||
* | |||
* @since 3.17 beta 1 | |||
*/ | |||
public TableStyleInfo getStyle() { | |||
if (! ctTable.isSetTableStyleInfo()) return null; | |||
return new XSSFTableStyleInfo(((XSSFSheet) getParent()).getWorkbook().getStylesSource(), ctTable.getTableStyleInfo()); | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import java.util.EnumMap; | |||
import java.util.Map; | |||
import org.apache.poi.ss.usermodel.DifferentialStyleProvider; | |||
import org.apache.poi.ss.usermodel.TableStyle; | |||
import org.apache.poi.ss.usermodel.TableStyleType; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxfs; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyle; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleElement; | |||
/** | |||
* {@link TableStyle} implementation for styles defined in the OOXML styles.xml. | |||
* Also used for built-in styles via dummy XML generated from presetTableStyles.xml. | |||
*/ | |||
public class XSSFTableStyle implements TableStyle { | |||
private final String name; | |||
private final Map<TableStyleType, DifferentialStyleProvider> elementMap = new EnumMap<TableStyleType, DifferentialStyleProvider>(TableStyleType.class); | |||
/** | |||
* @param dxfs | |||
* @param tableStyle | |||
*/ | |||
public XSSFTableStyle(CTDxfs dxfs, CTTableStyle tableStyle) { | |||
this.name = tableStyle.getName(); | |||
for (CTTableStyleElement element : tableStyle.getTableStyleElementList()) { | |||
TableStyleType type = TableStyleType.valueOf(element.getType().toString()); | |||
DifferentialStyleProvider dstyle = null; | |||
if (element.isSetDxfId()) { | |||
int idx = (int) element.getDxfId() -1; | |||
CTDxf dxf; | |||
if (idx >= 0 && idx < dxfs.getCount()) { | |||
dxf = dxfs.getDxfArray(idx); | |||
} else { | |||
dxf = null; | |||
} | |||
if (dxf != null) dstyle = new XSSFDxfStyleProvider(dxf); | |||
} | |||
elementMap.put(type, dstyle); | |||
} | |||
} | |||
public String getName() { | |||
return name; | |||
} | |||
public DifferentialStyleProvider getStyle(TableStyleType type) { | |||
return elementMap.get(type); | |||
} | |||
} |
@@ -0,0 +1,55 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.apache.poi.ss.usermodel.TableStyle; | |||
import org.apache.poi.ss.usermodel.TableStyleInfo; | |||
import org.apache.poi.xssf.model.StylesTable; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo; | |||
/** | |||
* Wrapper for the CT class, to cache values and add style lookup | |||
*/ | |||
public class XSSFTableStyleInfo implements TableStyleInfo { | |||
private final boolean columnStripes; | |||
private final boolean rowStripes; | |||
private final boolean firstColumn; | |||
private final boolean lastColumn; | |||
private final TableStyle style; | |||
/** | |||
* @param stylesTable | |||
* @param tableStyleInfo | |||
*/ | |||
public XSSFTableStyleInfo(StylesTable stylesTable, CTTableStyleInfo tableStyleInfo) { | |||
this.columnStripes = tableStyleInfo.getShowColumnStripes(); | |||
this.rowStripes = tableStyleInfo.getShowRowStripes(); | |||
this.firstColumn = tableStyleInfo.getShowFirstColumn(); | |||
this.lastColumn = tableStyleInfo.getShowLastColumn(); | |||
this.style = stylesTable.getTableStyle(tableStyleInfo.getName()); | |||
} | |||
public boolean isShowColumnStripes() { | |||
return columnStripes; | |||
} | |||
public boolean isShowRowStripes() { | |||
return rowStripes; | |||
} | |||
public boolean isShowFirstColumn() { | |||
return firstColumn; | |||
} | |||
public boolean isShowLastColumn() { | |||
return lastColumn; | |||
} | |||
public String getName() { | |||
return style.getName(); | |||
} | |||
public TableStyle getStyle() { | |||
return style; | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
import org.apache.poi.ss.usermodel.DifferentialStyleProvider; | |||
import org.apache.poi.ss.usermodel.FontFormatting; | |||
import org.apache.poi.ss.usermodel.PatternFormatting; | |||
import org.apache.poi.ss.usermodel.Table; | |||
import org.apache.poi.ss.usermodel.TableStyle; | |||
import org.apache.poi.ss.usermodel.TableStyleInfo; | |||
import org.apache.poi.ss.usermodel.TableStyleType; | |||
import org.apache.poi.xssf.XSSFTestDataSamples; | |||
import org.junit.Test; | |||
/** | |||
* Test built-in table styles | |||
*/ | |||
public class TestTableStyles { | |||
/** | |||
* Test that a built-in style is initialized properly | |||
*/ | |||
@Test | |||
public void testBuiltinStyleInit() { | |||
TableStyle style = XSSFBuiltinTableStyle.TableStyleMedium2.getStyle(); | |||
assertNotNull("no style found for Medium2", style); | |||
assertNull("Should not have style info for blankRow", style.getStyle(TableStyleType.blankRow)); | |||
DifferentialStyleProvider headerRow = style.getStyle(TableStyleType.headerRow); | |||
assertNotNull("no header row style", headerRow); | |||
FontFormatting font = headerRow.getFontFormatting(); | |||
assertNotNull("No header row font formatting", font); | |||
assertTrue("header row not bold", font.isBold()); | |||
PatternFormatting fill = headerRow.getPatternFormatting(); | |||
assertNotNull("No header fill", fill); | |||
assertEquals("wrong header fill", 4, ((XSSFColor) fill.getFillBackgroundColorColor()).getTheme()); | |||
} | |||
@Test | |||
public void testCustomStyle() throws Exception { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("tableStyle.xlsx"); | |||
Table table = wb.getTable("Table1"); | |||
assertNotNull("missing table", table); | |||
TableStyleInfo style = table.getStyle(); | |||
assertNotNull("Missing table style info", style); | |||
assertNotNull("Missing table style", style.getStyle()); | |||
assertEquals("Wrong name", "TestTableStyle", style.getName()); | |||
assertEquals("Wrong name", "TestTableStyle", style.getStyle().getName()); | |||
DifferentialStyleProvider firstColumn = style.getStyle().getStyle(TableStyleType.firstColumn); | |||
assertNotNull("no first column style", firstColumn); | |||
FontFormatting font = firstColumn.getFontFormatting(); | |||
assertNotNull("no first col font", font); | |||
assertTrue("wrong first col bold", font.isBold()); | |||
wb.close(); | |||
} | |||
} |