347 lines
8.8 KiB
Java
347 lines
8.8 KiB
Java
/* ====================================================================
|
|
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 com.moparisthebest.poi.hssf.usermodel;
|
|
|
|
|
|
/**
|
|
* Common class for {@link HSSFHeader} and {@link HSSFFooter}.
|
|
*/
|
|
public abstract class HeaderFooter implements com.moparisthebest.poi.ss.usermodel.HeaderFooter {
|
|
|
|
protected HeaderFooter() {
|
|
//
|
|
}
|
|
|
|
/**
|
|
* @return the internal text representation (combining center, left and right parts).
|
|
* Possibly empty string if no header or footer is set. Never <code>null</code>.
|
|
*/
|
|
protected abstract String getRawText();
|
|
|
|
private String[] splitParts() {
|
|
String text = getRawText();
|
|
// default values
|
|
String _left = "";
|
|
String _center = "";
|
|
String _right = "";
|
|
|
|
outer:
|
|
while (text.length() > 1) {
|
|
if (text.charAt(0) != '&') {
|
|
// Mimics the behaviour of Excel, which would put it in the center.
|
|
_center = text;
|
|
break;
|
|
}
|
|
int pos = text.length();
|
|
switch (text.charAt(1)) {
|
|
case 'L':
|
|
if (text.indexOf("&C") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&C"));
|
|
}
|
|
if (text.indexOf("&R") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&R"));
|
|
}
|
|
_left = text.substring(2, pos);
|
|
text = text.substring(pos);
|
|
break;
|
|
case 'C':
|
|
if (text.indexOf("&L") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&L"));
|
|
}
|
|
if (text.indexOf("&R") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&R"));
|
|
}
|
|
_center = text.substring(2, pos);
|
|
text = text.substring(pos);
|
|
break;
|
|
case 'R':
|
|
if (text.indexOf("&C") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&C"));
|
|
}
|
|
if (text.indexOf("&L") >= 0) {
|
|
pos = Math.min(pos, text.indexOf("&L"));
|
|
}
|
|
_right = text.substring(2, pos);
|
|
text = text.substring(pos);
|
|
break;
|
|
default:
|
|
// Mimics the behaviour of Excel, which would put it in the center.
|
|
_center = text;
|
|
break outer;
|
|
}
|
|
}
|
|
return new String[] { _left, _center, _right, };
|
|
}
|
|
|
|
/**
|
|
* @return the left side of the header or footer.
|
|
*/
|
|
public final String getLeft() {
|
|
return splitParts()[0];
|
|
}
|
|
|
|
/**
|
|
* @param newLeft The string to set as the left side.
|
|
*/
|
|
public final void setLeft(String newLeft) {
|
|
updatePart(0, newLeft);
|
|
}
|
|
|
|
/**
|
|
* @return the center of the header or footer.
|
|
*/
|
|
public final String getCenter() {
|
|
return splitParts()[1];
|
|
}
|
|
|
|
/**
|
|
* @param newCenter The string to set as the center.
|
|
*/
|
|
public final void setCenter(String newCenter) {
|
|
updatePart(1, newCenter);
|
|
}
|
|
|
|
/**
|
|
* @return The right side of the header or footer.
|
|
*/
|
|
public final String getRight() {
|
|
return splitParts()[2];
|
|
}
|
|
|
|
/**
|
|
* @param newRight The string to set as the right side.
|
|
*/
|
|
public final void setRight(String newRight) {
|
|
updatePart(2, newRight);
|
|
}
|
|
|
|
private void updatePart(int partIndex, String newValue) {
|
|
String[] parts = splitParts();
|
|
parts[partIndex] = newValue == null ? "" : newValue;
|
|
updateHeaderFooterText(parts);
|
|
}
|
|
/**
|
|
* Creates the complete footer string based on the left, center, and middle
|
|
* strings.
|
|
*/
|
|
private void updateHeaderFooterText(String[] parts) {
|
|
String _left = parts[0];
|
|
String _center = parts[1];
|
|
String _right = parts[2];
|
|
|
|
if (_center.length() < 1 && _left.length() < 1 && _right.length() < 1) {
|
|
setHeaderFooterText("");
|
|
return;
|
|
}
|
|
StringBuilder sb = new StringBuilder(64);
|
|
sb.append("&C");
|
|
sb.append(_center);
|
|
sb.append("&L");
|
|
sb.append(_left);
|
|
sb.append("&R");
|
|
sb.append(_right);
|
|
String text = sb.toString();
|
|
setHeaderFooterText(text);
|
|
}
|
|
|
|
/**
|
|
* @param text the new header footer text (contains mark-up tags). Possibly
|
|
* empty string never <code>null</code>
|
|
*/
|
|
protected abstract void setHeaderFooterText(String text);
|
|
|
|
/**
|
|
* @param size
|
|
* the new font size
|
|
* @return The mark-up tag representing a new font size
|
|
*/
|
|
public static String fontSize(short size) {
|
|
return "&" + size;
|
|
}
|
|
|
|
/**
|
|
* @param font
|
|
* the new font
|
|
* @param style
|
|
* the fonts style, one of regular, italic, bold, italic bold or
|
|
* bold italic
|
|
* @return The mark-up tag representing a new font size
|
|
*/
|
|
public static String font(String font, String style) {
|
|
return "&\"" + font + "," + style + "\"";
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing the current page number
|
|
*/
|
|
public static String page() {
|
|
return MarkupTag.PAGE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing the number of pages
|
|
*/
|
|
public static String numPages() {
|
|
return MarkupTag.NUM_PAGES_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing the current date date
|
|
*/
|
|
public static String date() {
|
|
return MarkupTag.DATE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing current time
|
|
*/
|
|
public static String time() {
|
|
return MarkupTag.TIME_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing the current file name
|
|
*/
|
|
public static String file() {
|
|
return MarkupTag.FILE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag representing the current tab (sheet) name
|
|
*/
|
|
public static String tab() {
|
|
return MarkupTag.SHEET_NAME_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for start bold
|
|
*/
|
|
public static String startBold() {
|
|
return MarkupTag.BOLD_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for end bold
|
|
*/
|
|
public static String endBold() {
|
|
return MarkupTag.BOLD_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for start underline
|
|
*/
|
|
public static String startUnderline() {
|
|
return MarkupTag.UNDERLINE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for end underline
|
|
*/
|
|
public static String endUnderline() {
|
|
return MarkupTag.UNDERLINE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for start double underline
|
|
*/
|
|
public static String startDoubleUnderline() {
|
|
return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* @return The mark-up tag for end double underline
|
|
*/
|
|
public static String endDoubleUnderline() {
|
|
return MarkupTag.DOUBLE_UNDERLINE_FIELD.getRepresentation();
|
|
}
|
|
|
|
/**
|
|
* Removes any fields (eg macros, page markers etc) from the string.
|
|
* Normally used to make some text suitable for showing to humans, and the
|
|
* resultant text should not normally be saved back into the document!
|
|
*/
|
|
public static String stripFields(String pText) {
|
|
int pos;
|
|
|
|
// Check we really got something to work on
|
|
if (pText == null || pText.length() == 0) {
|
|
return pText;
|
|
}
|
|
|
|
String text = pText;
|
|
|
|
// Firstly, do the easy ones which are static
|
|
for (MarkupTag mt : MarkupTag.values()) {
|
|
String seq = mt.getRepresentation();
|
|
while ((pos = text.indexOf(seq)) > -1) {
|
|
text = text.substring(0, pos) + text.substring(pos + seq.length());
|
|
}
|
|
}
|
|
|
|
// Now do the tricky, dynamic ones
|
|
// These are things like font sizes and font names
|
|
text = text.replaceAll("\\&\\d+", "");
|
|
text = text.replaceAll("\\&\".*?,.*?\"", "");
|
|
|
|
// All done
|
|
return text;
|
|
}
|
|
|
|
private enum MarkupTag {
|
|
SHEET_NAME_FIELD ("&A", false),
|
|
DATE_FIELD ("&D", false),
|
|
FILE_FIELD ("&F", false),
|
|
FULL_FILE_FIELD ("&Z", false),
|
|
PAGE_FIELD ("&P", false),
|
|
TIME_FIELD ("&T", false),
|
|
NUM_PAGES_FIELD ("&N", false),
|
|
|
|
PICTURE_FIELD ("&G", false),
|
|
|
|
BOLD_FIELD ("&B", true),
|
|
ITALIC_FIELD ("&I", true),
|
|
STRIKETHROUGH_FIELD ("&S", true),
|
|
SUBSCRIPT_FIELD ("&Y", true),
|
|
SUPERSCRIPT_FIELD ("&X", true),
|
|
UNDERLINE_FIELD ("&U", true),
|
|
DOUBLE_UNDERLINE_FIELD ("&E", true),
|
|
;
|
|
|
|
private final String _representation;
|
|
private final boolean _occursInPairs;
|
|
private MarkupTag(String sequence, boolean occursInPairs) {
|
|
_representation = sequence;
|
|
_occursInPairs = occursInPairs;
|
|
}
|
|
/**
|
|
* @return The character sequence that marks this field
|
|
*/
|
|
public String getRepresentation() {
|
|
return _representation;
|
|
}
|
|
|
|
/**
|
|
* @return true if this markup tag normally comes in a pair, eg turn on
|
|
* underline / turn off underline
|
|
*/
|
|
public boolean occursPairs() {
|
|
return _occursInPairs;
|
|
}
|
|
}
|
|
}
|