applied patch #46003 by Gisella Bronzetti

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@705701 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-10-17 18:43:37 +00:00
parent 96d360ff21
commit f90843cd7f
4 changed files with 384 additions and 69 deletions

View File

@ -0,0 +1,42 @@
/* ====================================================================
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.xssf.usermodel.examples;
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class SetPrintArea {
public static void main(String[]args) throws Exception {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
//wb.setPrintArea(0, "$A$1:$C$2");
//sets the print area for the first sheet
//Alternatively:
wb.setPrintArea(0, 1, 2, 0, 3); //is equivalent to using the name reference (See the JavaDocs for more details)
// Create various cells and rows for spreadsheet.
FileOutputStream fileOut = new FileOutputStream("printArea.xlsx");
wb.write(fileOut);
fileOut.close();
}
}

View File

@ -23,66 +23,165 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
* XSSF Implementation of a Named Range
*/
public class XSSFName implements Name {
private XSSFWorkbook workbook;
private CTDefinedName ctName;
protected XSSFName(XSSFWorkbook workbook) {
this.workbook = workbook;
this.ctName = CTDefinedName.Factory.newInstance();
}
protected XSSFName(CTDefinedName name, XSSFWorkbook workbook) {
this.workbook = workbook;
this.ctName = name;
}
public boolean isFunctionName() {
// TODO Figure out how HSSF does this, and do the same!
return ctName.getFunction(); // maybe this works - verify
}
/**
* Returns the underlying named range object
*/
protected CTDefinedName getCTName() {
return ctName;
}
public String getNameName() {
return ctName.getName();
}
public void setNameName(String nameName) {
ctName.setName(nameName);
/**
* The following built-in names are defined in this SpreadsheetML
* specification:
* Built-in names reserved by SpreadsheetML begin with "_xlnm.". End users shall not use
* this string for custom names in the user interface.
*/
/**
* this defined name specifies the workbook's print area
*/
public final static String BUILTIN_PRINT_AREA = "_xlnm.Print_Area";
/**
* this defined name specifies the row(s) or column(s) to repeat
* at the top of each printed page.
*/
public final static String BUILTIN_PRINT_TITLE = "_xlnm.Print_Titles";
//Filter & Advanced Filter
/**
* this defined name refers to a range containing the criteria values
* to be used in applying an advanced filter to a range of data
*/
public final static String BUILTIN_CRITERIA = "_xlnm.Criteria:";
/**
* this defined name refers to the range containing the filtered
* output values resulting from applying an advanced filter criteria to a source
* range
*/
public final static String BUILTIN_EXTRACT = "_xlnm.Extract:";
/**
* can be one of the following
* a. this defined name refers to a range to which an advanced filter has been
* applied. This represents the source data range, unfiltered.
* b. This defined name refers to a range to which an AutoFilter has been
* applied
*/
public final static String BUILTIN_FILTER_DB = "_xlnm._FilterDatabase:";
//Miscellaneous
/**
* the defined name refers to a consolidation area
*/
public final static String BUILTIN_CONSOLIDATE_AREA = "_xlnm.Consolidate_Area";
/**
* the range specified in the defined name is from a database data source
*/
public final static String BUILTIN_DATABASE = "_xlnm.Database";
/**
* the defined name refers to a sheet title.
*/
public final static String BUILTIN_SHEET_TITLE = "_xlnm.Sheet_Title";
private XSSFWorkbook workbook;
private CTDefinedName ctName;
protected XSSFName(XSSFWorkbook workbook) {
this.workbook = workbook;
this.ctName = CTDefinedName.Factory.newInstance();
}
protected XSSFName(CTDefinedName name, XSSFWorkbook workbook) {
this.workbook = workbook;
this.ctName = name;
}
public boolean isFunctionName() {
// TODO Figure out how HSSF does this, and do the same!
return ctName.getFunction(); // maybe this works - verify
}
/**
* Returns the underlying named range object
*/
protected CTDefinedName getCTName() {
return ctName;
}
public String getNameName() {
return ctName.getName();
}
public void setNameName(String nameName) {
ctName.setName(nameName);
}
public String getReference() {
return ctName.getStringValue();
}
public void setReference(String ref) {
ctName.setStringValue(ref);
}
public void setLocalSheetId(int sheetId) {
ctName.setLocalSheetId(sheetId);
}
public int getLocalSheetId() {
return (int)ctName.getLocalSheetId();
}
public void setFunction(boolean value) {
ctName.setFunction(value);
}
public boolean getFunction() {
return ctName.getFunction();
}
public void setFunctionGroupId(int functionGroupId) {
ctName.setFunctionGroupId(functionGroupId);
}
public int getFunctionGroupId() {
return (int)ctName.getFunctionGroupId();
}
public String getSheetName() {
if(ctName.isSetLocalSheetId()) {
// Given as explicit sheet id
long sheetId = ctName.getLocalSheetId();
if(sheetId >= 0) {
return workbook.getSheetName((int)sheetId);
}
} else {
// Is it embeded in the reference itself?
int excl = getReference().indexOf('!');
if(excl > -1) {
return getReference().substring(0, excl);
}
}
public String getReference() {
return ctName.getStringValue();
}
public void setReference(String ref) {
ctName.setStringValue(ref);
}
public String getSheetName() {
if(ctName.isSetLocalSheetId()) {
// Given as explicit sheet id
long sheetId = ctName.getLocalSheetId();
if(sheetId >= 0) {
return workbook.getSheetName((int)sheetId);
}
} else {
// Is it embeded in the reference itself?
int excl = getReference().indexOf('!');
if(excl > -1) {
return getReference().substring(0, excl);
}
}
// Not given at all
return null;
}
// Not given at all
return null;
}
public String getComment() {
return ctName.getComment();
}
public void setComment(String comment) {
ctName.setComment(comment);
}
public int hashCode(){
return ctName.toString().hashCode();
}
public boolean equals(Object o){
if(!(o instanceof XSSFName)) return false;
XSSFName cf = (XSSFName)o;
return ctName.toString().equals(cf.getCTName().toString());
}
public String getComment() {
return ctName.getComment();
}
public void setComment(String comment) {
ctName.setComment(comment);
}
}

View File

@ -28,6 +28,7 @@ import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.PackageHelper;
@ -604,9 +605,16 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
return this.sheets.size();
}
public String getPrintArea(int sheetIndex) {
// TODO Auto-generated method stub
return null;
/**
* Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified.
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @return String Null if no print area has been defined
*/
public String getPrintArea(int sheetIndex) {
XSSFName name = getSpecificBuiltinRecord(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
if (name == null) return null;
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
return name.getReference();
}
/**
@ -826,21 +834,119 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
bookView.setActiveTab(index);
}
/**
* Sets the printarea for the sheet provided
* <p>
* i.e. Reference = $A$1:$B$2
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @param reference Valid name Reference for the Print Area
*/
public void setPrintArea(int sheetIndex, String reference) {
// TODO Auto-generated method stub
XSSFName name = getSpecificBuiltinRecord(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
if (name == null) {
name = createBuiltInName(XSSFName.BUILTIN_PRINT_AREA, sheetIndex);
namedRanges.add(name);
}
name.setReference(reference);
}
/**
* For the Convenience of Java Programmers maintaining pointers.
* @see #setPrintArea(int, String)
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
* @param startColumn Column to begin printarea
* @param endColumn Column to end the printarea
* @param startRow Row to begin the printarea
* @param endRow Row to end the printarea
*/
public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
// TODO Auto-generated method stub
String reference=getReferencePrintArea(getSheetName(sheetIndex), startColumn, endColumn, startRow, endRow);
setPrintArea(sheetIndex, reference);
}
public void setRepeatingRowsAndColumns(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
// TODO Auto-generated method stub
/**
* Sets the repeating rows and columns for a sheet.
* This is function is included in the workbook
* because it creates/modifies name records which are stored at the
* workbook level.
* <p>
* To set just repeating columns:
* <pre>
* workbook.setRepeatingRowsAndColumns(0,0,1,-1,-1);
* </pre>
* To set just repeating rows:
* <pre>
* workbook.setRepeatingRowsAndColumns(0,-1,-1,0,4);
* </pre>
* To remove all repeating rows and columns for a sheet.
* <pre>
* workbook.setRepeatingRowsAndColumns(0,-1,-1,-1,-1);
* </pre>
*
* @param sheetIndex 0 based index to sheet.
* @param startColumn 0 based start of repeating columns.
* @param endColumn 0 based end of repeating columns.
* @param startRow 0 based start of repeating rows.
* @param endRow 0 based end of repeating rows.
*/
public void setRepeatingRowsAndColumns(int sheetIndex,
int startColumn, int endColumn,
int startRow, int endRow) {
//TODO
}
private String getReferencePrintArea(String sheetName, int startC, int endC, int startR, int endR) {
//windows excel example: Sheet1!$C$3:$E$4
CellReference colRef = new CellReference(sheetName, startR, startC, true, true);
CellReference colRef2 = new CellReference(sheetName, endR, endC, true, true);
String c = "'" + sheetName + "'!$" + colRef.getCellRefParts()[2] + "$" + colRef.getCellRefParts()[1] + ":$" + colRef2.getCellRefParts()[2] + "$" + colRef2.getCellRefParts()[1];
return c;
}
//****************** NAME RANGE *************************
private CTDefinedNames getDefinedNames() {
return workbook.getDefinedNames() == null ? workbook.addNewDefinedNames() : workbook.getDefinedNames();
}
public XSSFName getSpecificBuiltinRecord(String builtInCode, int sheetNumber) {
for (XSSFName name : namedRanges) {
if (name.getNameName().equalsIgnoreCase(builtInCode) && name.getLocalSheetId() == sheetNumber) {
return name;
}
}
return null;
}
/**
* Generates a NameRecord to represent a built-in region
* @return a new NameRecord
*/
public XSSFName createBuiltInName(String builtInName, int sheetNumber) {
if (sheetNumber < 0 || sheetNumber+1 > Short.MAX_VALUE) {
throw new IllegalArgumentException("Sheet number ["+sheetNumber+"]is not valid ");
}
CTDefinedName nameRecord=getDefinedNames().addNewDefinedName();
nameRecord.setName(builtInName);
nameRecord.setLocalSheetId(sheetNumber);
XSSFName name=new XSSFName(nameRecord,this);
//while(namedRanges.contains(name)) {
for(XSSFName nr : namedRanges){
if(nr.equals(name))
throw new RuntimeException("Builtin (" + builtInName
+ ") already exists for sheet (" + sheetNumber + ")");
}
return name;
}
//*******************************************
/**
* We only set one sheet as selected for compatibility with HSSF.
*/

View File

@ -31,6 +31,7 @@ import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.StylesSource;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.StylesTable;
import org.openxml4j.opc.ContentTypes;
@ -150,6 +151,73 @@ public final class TestXSSFWorkbook extends TestCase {
workbook.removeSheetAt(0);
assertEquals(0, workbook.getNumberOfSheets());
}
public void testPrintArea(){
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Test Print Area");
String sheetName = workbook.getSheetName(0);
// String reference = sheetName+"!$A$1:$B$1";
// workbook.setPrintArea(0, reference);
workbook.setPrintArea(0,1,5,4,9);
String retrievedPrintArea = workbook.getPrintArea(0);
//assertNotNull("Print Area not defined for first sheet", retrievedPrintArea);
assertEquals("'"+sheetName+"'!$B$5:$F$10", retrievedPrintArea);
}
public void _testRepeatingRowsAndColums() {
// First test that setting RR&C for same sheet more than once only creates a
// single Print_Titles built-in record
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet("FirstSheet");
// set repeating rows and columns twice for the first sheet
for (int i = 0; i < 2; i++) {
wb.setRepeatingRowsAndColumns(0, 0, 0, 0, 3);
//sheet.createFreezePane(0, 3);
}
assertEquals(1, wb.getNumberOfNames());
XSSFName nr1 = wb.getNameAt(0);
assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr1.getNameName());
assertEquals("'FirstSheet'!$A:$A,'FirstSheet'!$1:$4", nr1.getReference());
// Save and re-open
XSSFWorkbook nwb = XSSFTestDataSamples.writeOutAndReadBack(wb);
assertEquals(1, nwb.getNumberOfNames());
nr1 = nwb.getNameAt(0);
assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr1.getNameName());
assertEquals("'FirstSheet'!$A:$A,'FirstSheet'!$1:$4", nr1.getReference());
// check that setting RR&C on a second sheet causes a new Print_Titles built-in
// name to be created
sheet = nwb.createSheet("SecondSheet");
nwb.setRepeatingRowsAndColumns(1, 1, 2, 0, 0);
assertEquals(2, nwb.getNumberOfNames());
XSSFName nr2 = nwb.getNameAt(1);
assertEquals(XSSFName.BUILTIN_PRINT_TITLE, nr2.getNameName());
assertEquals("'SecondSheet'!$B:$C,'SecondSheet'!$1:$1", nr2.getReference());
if (false) {
// In case you fancy checking in excel, to ensure it
// won't complain about the file now
try {
File tempFile = File.createTempFile("POI-45126-", ".xlsx");
FileOutputStream fout = new FileOutputStream(tempFile);
nwb.write(fout);
fout.close();
System.out.println("check out " + tempFile.getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* Tests that we can save a new document