mirror of https://github.com/apache/poi.git
Start on headers/footers support
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684349 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8a0c521503
commit
e00116900d
|
@ -562,6 +562,10 @@ public class HWPFDocument extends POIDocument
|
||||||
{
|
{
|
||||||
return _dataStream;
|
return _dataStream;
|
||||||
}
|
}
|
||||||
|
public byte[] getTableStream()
|
||||||
|
{
|
||||||
|
return _tableStream;
|
||||||
|
}
|
||||||
|
|
||||||
public int registerList(HWPFList list)
|
public int registerList(HWPFList list)
|
||||||
{
|
{
|
||||||
|
|
|
@ -261,6 +261,27 @@ public class FileInformationBlock extends FIBAbstractType
|
||||||
_fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn);
|
_fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the offset to the PlcfHdd, in the table stream,
|
||||||
|
* i.e. fcPlcfHdd
|
||||||
|
*/
|
||||||
|
public int getPlcfHddOffset() {
|
||||||
|
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFHDD);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return the size of the PlcfHdd, in the table stream,
|
||||||
|
* i.e. lcbPlcfHdd
|
||||||
|
*/
|
||||||
|
public int getPlcfHddSize() {
|
||||||
|
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFHDD);
|
||||||
|
}
|
||||||
|
public void setPlcfHddOffset(int fcPlcfHdd) {
|
||||||
|
_fieldHandler.setFieldOffset(FIBFieldHandler.PLCFHDD, fcPlcfHdd);
|
||||||
|
}
|
||||||
|
public void setPlcfHddSize(int lcbPlcfHdd) {
|
||||||
|
_fieldHandler.setFieldSize(FIBFieldHandler.PLCFHDD, lcbPlcfHdd);
|
||||||
|
}
|
||||||
|
|
||||||
public int getFcSttbSavedBy()
|
public int getFcSttbSavedBy()
|
||||||
{
|
{
|
||||||
return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY);
|
return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY);
|
||||||
|
|
|
@ -54,7 +54,9 @@ public class PlexOfCps
|
||||||
*/
|
*/
|
||||||
public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
|
public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
|
||||||
{
|
{
|
||||||
|
// Figure out the number we hold
|
||||||
_count = (size - 4)/(4 + sizeOfStruct);
|
_count = (size - 4)/(4 + sizeOfStruct);
|
||||||
|
|
||||||
_sizeOfStruct = sizeOfStruct;
|
_sizeOfStruct = sizeOfStruct;
|
||||||
_props = new ArrayList(_count);
|
_props = new ArrayList(_count);
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,155 @@
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hwpf.usermodel;
|
package org.apache.poi.hwpf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
import org.apache.poi.hwpf.model.FileInformationBlock;
|
||||||
|
import org.apache.poi.hwpf.model.GenericPropertyNode;
|
||||||
|
import org.apache.poi.hwpf.model.PlexOfCps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A HeaderStory is a Header, a Footer, or footnote/endnote
|
* A HeaderStory is a Header, a Footer, or footnote/endnote
|
||||||
* separator.
|
* separator.
|
||||||
* All the Header Stories get stored in the same Range in the
|
* All the Header Stories get stored in the same Range in the
|
||||||
* document, and this handles getting out all the individual
|
* document, and this handles getting out all the individual
|
||||||
* parts.
|
* parts.
|
||||||
|
*
|
||||||
|
* WARNING - you shouldn't change the headers or footers,
|
||||||
|
* as offsets are not yet updated!
|
||||||
*/
|
*/
|
||||||
public class HeaderStories {
|
public class HeaderStories {
|
||||||
private Range headerStories;
|
private Range headerStories;
|
||||||
public HeaderStories(Range headerStories) {
|
private PlexOfCps plcfHdd;
|
||||||
this.headerStories = headerStories;
|
|
||||||
|
public HeaderStories(HWPFDocument doc) {
|
||||||
|
this.headerStories = doc.getHeaderStoryRange();
|
||||||
|
FileInformationBlock fib = doc.getFileInformationBlock();
|
||||||
|
|
||||||
|
// If there's no PlcfHdd, nothing to do
|
||||||
|
if(fib.getCcpHdd() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(fib.getPlcfHddSize() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the PlcfHdd
|
||||||
|
plcfHdd = new PlexOfCps(
|
||||||
|
doc.getTableStream(), fib.getPlcfHddOffset(),
|
||||||
|
fib.getPlcfHddSize(), 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFootnoteSeparator() {
|
||||||
|
return getAt(0);
|
||||||
|
}
|
||||||
|
public String getFootnoteContSeparator() {
|
||||||
|
return getAt(1);
|
||||||
|
}
|
||||||
|
public String getFootnoteContNote() {
|
||||||
|
return getAt(2);
|
||||||
|
}
|
||||||
|
public String getEndnoteSeparator() {
|
||||||
|
return getAt(3);
|
||||||
|
}
|
||||||
|
public String getEndnoteContSeparator() {
|
||||||
|
return getAt(4);
|
||||||
|
}
|
||||||
|
public String getEndnoteContNote() {
|
||||||
|
return getAt(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getEvenHeader() {
|
||||||
|
return getAt(6+0);
|
||||||
|
}
|
||||||
|
public String getOddHeader() {
|
||||||
|
return getAt(6+1);
|
||||||
|
}
|
||||||
|
public String getFirstHeader() {
|
||||||
|
return getAt(6+4);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the correct, defined header for the given
|
||||||
|
* one based page
|
||||||
|
* @param pageNumber The one based page number
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getHeader(int pageNumber) {
|
||||||
|
// First page header is optional, only return
|
||||||
|
// if it's set
|
||||||
|
if(pageNumber == 1) {
|
||||||
|
if(getFirstHeader().length() > 0) {
|
||||||
|
return getFirstHeader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Even page header is optional, only return
|
||||||
|
// if it's set
|
||||||
|
if(pageNumber % 2 == 0) {
|
||||||
|
if(getEvenHeader().length() > 0) {
|
||||||
|
return getEvenHeader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Odd is the default
|
||||||
|
return getOddHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getEvenFooter() {
|
||||||
|
return getAt(6+2);
|
||||||
|
}
|
||||||
|
public String getOddFooter() {
|
||||||
|
return getAt(6+3);
|
||||||
|
}
|
||||||
|
public String getFirstFooter() {
|
||||||
|
return getAt(6+5);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the correct, defined footer for the given
|
||||||
|
* one based page
|
||||||
|
* @param pageNumber The one based page number
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getFooter(int pageNumber) {
|
||||||
|
// First page footer is optional, only return
|
||||||
|
// if it's set
|
||||||
|
if(pageNumber == 1) {
|
||||||
|
if(getFirstFooter().length() > 0) {
|
||||||
|
return getFirstFooter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Even page footer is optional, only return
|
||||||
|
// if it's set
|
||||||
|
if(pageNumber % 2 == 0) {
|
||||||
|
if(getEvenFooter().length() > 0) {
|
||||||
|
return getEvenFooter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Odd is the default
|
||||||
|
return getOddFooter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string that's pointed to by the
|
||||||
|
* given plcfHdd index
|
||||||
|
*/
|
||||||
|
private String getAt(int plcfHddIndex) {
|
||||||
|
if(plcfHdd == null) return null;
|
||||||
|
|
||||||
|
GenericPropertyNode prop = plcfHdd.getProperty(plcfHddIndex);
|
||||||
|
if(prop.getStart() == prop.getEnd()) {
|
||||||
|
// Empty story
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the contents
|
||||||
|
return headerStories.text().substring(prop.getStart(), prop.getEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Range getRange() {
|
||||||
|
return headerStories;
|
||||||
|
}
|
||||||
|
protected PlexOfCps getPlcfHdd() {
|
||||||
|
return plcfHdd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/* ====================================================================
|
||||||
|
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.hwpf.usermodel;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for the handling of header stories into
|
||||||
|
* headers, footers etc
|
||||||
|
*/
|
||||||
|
public class TestHeaderStories extends TestCase {
|
||||||
|
private HWPFDocument none;
|
||||||
|
private HWPFDocument header;
|
||||||
|
private HWPFDocument footer;
|
||||||
|
private HWPFDocument headerFooter;
|
||||||
|
private HWPFDocument oddEven;
|
||||||
|
private HWPFDocument diffFirst;
|
||||||
|
private HWPFDocument unicode;
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
String dirname = System.getProperty("HWPF.testdata.path");
|
||||||
|
|
||||||
|
none = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "NoHeadFoot.doc"))
|
||||||
|
);
|
||||||
|
header = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "ThreeColHead.doc"))
|
||||||
|
);
|
||||||
|
footer = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "ThreeColFoot.doc"))
|
||||||
|
);
|
||||||
|
headerFooter = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "SimpleHeadThreeColFoot.doc"))
|
||||||
|
);
|
||||||
|
oddEven = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "PageSpecificHeadFoot.doc"))
|
||||||
|
);
|
||||||
|
diffFirst = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "DiffFirstPageHeadFoot.doc"))
|
||||||
|
);
|
||||||
|
unicode = new HWPFDocument(
|
||||||
|
new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNone() throws Exception {
|
||||||
|
HeaderStories hs = new HeaderStories(none);
|
||||||
|
|
||||||
|
assertNull(hs.getPlcfHdd());
|
||||||
|
assertEquals(0, hs.getRange().text().length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testHeader() throws Exception {
|
||||||
|
HeaderStories hs = new HeaderStories(header);
|
||||||
|
|
||||||
|
assertEquals(60, hs.getRange().text().length());
|
||||||
|
|
||||||
|
// Should have the usual 6 separaters
|
||||||
|
// Then all 6 of the different header/footer kinds
|
||||||
|
// Finally a terminater
|
||||||
|
assertEquals(13, hs.getPlcfHdd().length());
|
||||||
|
|
||||||
|
assertEquals(215, hs.getRange().getStartOffset());
|
||||||
|
|
||||||
|
assertEquals(0, hs.getPlcfHdd().getProperty(0).getStart());
|
||||||
|
assertEquals(3, hs.getPlcfHdd().getProperty(1).getStart());
|
||||||
|
assertEquals(6, hs.getPlcfHdd().getProperty(2).getStart());
|
||||||
|
assertEquals(6, hs.getPlcfHdd().getProperty(3).getStart());
|
||||||
|
assertEquals(9, hs.getPlcfHdd().getProperty(4).getStart());
|
||||||
|
assertEquals(12, hs.getPlcfHdd().getProperty(5).getStart());
|
||||||
|
|
||||||
|
assertEquals(12, hs.getPlcfHdd().getProperty(6).getStart());
|
||||||
|
assertEquals(12, hs.getPlcfHdd().getProperty(7).getStart());
|
||||||
|
assertEquals(59, hs.getPlcfHdd().getProperty(8).getStart());
|
||||||
|
assertEquals(59, hs.getPlcfHdd().getProperty(9).getStart());
|
||||||
|
assertEquals(59, hs.getPlcfHdd().getProperty(10).getStart());
|
||||||
|
assertEquals(59, hs.getPlcfHdd().getProperty(11).getStart());
|
||||||
|
|
||||||
|
assertEquals(59, hs.getPlcfHdd().getProperty(12).getStart());
|
||||||
|
|
||||||
|
assertEquals("\u0003\r\r", hs.getFootnoteSeparator());
|
||||||
|
assertEquals("\u0004\r\r", hs.getFootnoteContSeparator());
|
||||||
|
assertEquals("", hs.getFootnoteContNote());
|
||||||
|
assertEquals("\u0003\r\r", hs.getEndnoteSeparator());
|
||||||
|
assertEquals("\u0004\r\r", hs.getEndnoteContSeparator());
|
||||||
|
assertEquals("", hs.getEndnoteContNote());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue