Skip to content

Commit

Permalink
#242 Support footer and header
Browse files Browse the repository at this point in the history
PR #300
  • Loading branch information
SoltauFintel authored May 10, 2024
1 parent 6c58801 commit 6dec5d3
Show file tree
Hide file tree
Showing 16 changed files with 264 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public JxlsPoiTemplateFillerBuilder() {
withTransformerFactory(new PoiTransformerFactory());
withCommand(ImageCommand.COMMAND_NAME, ImageCommand.class);
withCommand(MergeCellsCommand.COMMAND_NAME, MergeCellsCommand.class);
withSheetCreator(new PoiSheetCreator());
}

public static JxlsPoiTemplateFillerBuilder newInstance() {
Expand Down
133 changes: 133 additions & 0 deletions jxls-poi/src/main/java/org/jxls/transform/poi/PoiSheetCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package org.jxls.transform.poi;

import org.apache.poi.ss.usermodel.HeaderFooter;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFHeaderFooterProperties;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jxls.builder.SheetCreator;

public class PoiSheetCreator implements SheetCreator {
private boolean cloneSheet = true;

/**
* @return true: use cloneSheet(), false: use createSheet()
*/
public boolean isCloneSheet() {
return cloneSheet;
}

/**
* @param cloneSheet true: use cloneSheet(), false: use createSheet()
*/
public void setCloneSheet(boolean cloneSheet) {
this.cloneSheet = cloneSheet;
}

@Override
public Object createSheet(Object workbook, String sourceSheetName, String targetSheetName) {
Sheet src;
Sheet dest;
if (cloneSheet && workbook instanceof XSSFWorkbook w) {
src = w.getSheet(sourceSheetName);
dest = w.cloneSheet(w.getSheetIndex(sourceSheetName), targetSheetName); // since JXLS 3.0
} else if (workbook instanceof Workbook w) {
src = w.getSheet(sourceSheetName);
dest = w.createSheet(targetSheetName);
} else {
throw new IllegalArgumentException("Parameter workbook must be of type Workbook");
}
copySheetSetup(src, dest);
copyPrintSetup(src, dest);
return dest;
}

protected void copySheetSetup(Sheet src, Sheet dest) {
int srcIndex = src.getWorkbook().getSheetIndex(src);
String area = src.getWorkbook().getPrintArea(srcIndex);
if (area != null) {
int destIndex = dest.getWorkbook().getSheetIndex(dest);
dest.getWorkbook().setPrintArea(destIndex, area.substring(area.indexOf("!") + 1));
}
dest.setAutobreaks(src.getAutobreaks());
for (int i : src.getColumnBreaks()) {
dest.setColumnBreak(i);
}
for (int i : src.getRowBreaks()) {
dest.setRowBreak(i);
}
dest.setDefaultColumnWidth(src.getDefaultColumnWidth());
dest.setDefaultRowHeight(src.getDefaultRowHeight());
dest.setDefaultRowHeightInPoints(src.getDefaultRowHeightInPoints());
dest.setDisplayGuts(src.getDisplayGuts());
dest.setFitToPage(src.getFitToPage());
dest.setForceFormulaRecalculation(src.getForceFormulaRecalculation());
dest.setHorizontallyCenter(src.getHorizontallyCenter());
dest.setMargin(Sheet.LeftMargin, src.getMargin(Sheet.LeftMargin));
dest.setMargin(Sheet.RightMargin, src.getMargin(Sheet.RightMargin));
dest.setMargin(Sheet.TopMargin, src.getMargin(Sheet.TopMargin));
dest.setMargin(Sheet.BottomMargin, src.getMargin(Sheet.BottomMargin));
dest.setMargin(Sheet.HeaderMargin, src.getMargin(Sheet.HeaderMargin));
dest.setMargin(Sheet.FooterMargin, src.getMargin(Sheet.FooterMargin));
dest.setPrintGridlines(src.isPrintGridlines());
dest.setRowSumsBelow(src.getRowSumsBelow());
dest.setRowSumsRight(src.getRowSumsRight());
dest.setVerticallyCenter(src.getVerticallyCenter());
dest.setDisplayFormulas(src.isDisplayFormulas());
dest.setDisplayGridlines(src.isDisplayGridlines());
dest.setDisplayZeros(src.isDisplayZeros());
dest.setPrintGridlines(src.isPrintGridlines());
dest.setDisplayRowColHeadings(src.isDisplayRowColHeadings());
dest.setRightToLeft(src.isRightToLeft());
dest.setRepeatingColumns(src.getRepeatingColumns());
dest.setRepeatingRows(src.getRepeatingRows());
copyHeaderOrFooter(src.getHeader(), dest.getHeader());
copyHeaderOrFooter(src.getFooter(), dest.getFooter());
if (src instanceof XSSFSheet xs && dest instanceof XSSFSheet xd) {
XSSFHeaderFooterProperties hfs = xs.getHeaderFooterProperties();
XSSFHeaderFooterProperties hfd = xd.getHeaderFooterProperties();
if (hfs.getDifferentOddEven()) {
copyHeaderOrFooter(xs.getEvenHeader(), xd.getEvenHeader());
copyHeaderOrFooter(xs.getEvenFooter(), xd.getEvenFooter());
copyHeaderOrFooter(xs.getOddHeader(), xd.getOddHeader());
copyHeaderOrFooter(xs.getOddFooter(), xd.getOddFooter());
}
hfd.setDifferentOddEven(hfs.getDifferentOddEven());
hfd.setDifferentFirst(hfs.getDifferentFirst());
hfd.setAlignWithMargins(hfs.getAlignWithMargins());
hfd.setScaleWithDoc(hfs.getScaleWithDoc());
}
dest.setZoom(100);
}

protected final void copyHeaderOrFooter(HeaderFooter src, HeaderFooter dest) {
dest.setLeft(src.getLeft());
dest.setCenter(src.getCenter());
dest.setRight(src.getRight());
}

protected void copyPrintSetup(Sheet src, Sheet dest) {
PrintSetup srcPrintSetup = src.getPrintSetup();
PrintSetup destPrintSetup = dest.getPrintSetup();
destPrintSetup.setCopies(srcPrintSetup.getCopies());
destPrintSetup.setDraft(srcPrintSetup.getDraft());
destPrintSetup.setFitHeight(srcPrintSetup.getFitHeight());
destPrintSetup.setFitWidth(srcPrintSetup.getFitWidth());
destPrintSetup.setFooterMargin(srcPrintSetup.getFooterMargin());
destPrintSetup.setHeaderMargin(srcPrintSetup.getHeaderMargin());
destPrintSetup.setHResolution(srcPrintSetup.getHResolution());
destPrintSetup.setLandscape(srcPrintSetup.getLandscape());
destPrintSetup.setLeftToRight(srcPrintSetup.getLeftToRight());
destPrintSetup.setNoColor(srcPrintSetup.getNoColor());
destPrintSetup.setNoOrientation(srcPrintSetup.getNoOrientation());
destPrintSetup.setNotes(srcPrintSetup.getNotes());
destPrintSetup.setPageStart(srcPrintSetup.getPageStart());
destPrintSetup.setPaperSize(srcPrintSetup.getPaperSize());
destPrintSetup.setScale(srcPrintSetup.getScale());
destPrintSetup.setUsePage(srcPrintSetup.getUsePage());
destPrintSetup.setValidSettings(srcPrintSetup.getValidSettings());
destPrintSetup.setVResolution(srcPrintSetup.getVResolution());
}
}
40 changes: 30 additions & 10 deletions jxls-poi/src/main/java/org/jxls/transform/poi/PoiTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jxls.builder.SheetCreator;
import org.jxls.common.AreaRef;
import org.jxls.common.CellData;
import org.jxls.common.CellRef;
Expand All @@ -46,7 +47,8 @@ public class PoiTransformer extends AbstractTransformer {
private InputStream inputStream;
private final boolean isSXSSF;
private JxlsLogger logger = new PoiExceptionLogger();

private SheetCreator sheetCreator;

/**
* @param workbook source workbook to transform
* @param streaming false: without streaming, true: with streaming (with default parameter values)
Expand Down Expand Up @@ -107,15 +109,8 @@ public void transform(CellRef srcCellRef, CellRef targetCellRef, Context context
if (cellData == null) {
return;
}
Sheet destSheet = workbook.getSheet(targetCellRef.getSheetName());
if (destSheet == null) {
destSheet = workbook.createSheet(targetCellRef.getSheetName());
PoiUtil.copySheetProperties(workbook.getSheet(srcCellRef.getSheetName()), destSheet);
}
Row destRow = destSheet.getRow(targetCellRef.getRow());
if (destRow == null) {
destRow = destSheet.createRow(targetCellRef.getRow());
}
Sheet destSheet = getSheet(srcCellRef, targetCellRef);
Row destRow = getRow(srcCellRef, targetCellRef, destSheet);
transformCell(srcCellRef, targetCellRef, context, updateRowHeightFlag, cellData, destSheet, destRow);
}

Expand All @@ -129,6 +124,26 @@ protected CellData isTransformable(CellRef srcCellRef, CellRef targetCellRef) {
}
return cellData;
}

protected Sheet getSheet(CellRef srcCellRef, CellRef targetCellRef) {
String targetSheetName = targetCellRef.getSheetName();
Sheet sheet = workbook.getSheet(targetSheetName);
if (sheet == null) {
if (sheetCreator == null) {
throw new JxlsException("Can not create sheet!");
}
sheet = (Sheet) sheetCreator.createSheet(workbook, srcCellRef.getSheetName(), targetSheetName);
}
return sheet;
}

protected Row getRow(CellRef srcCellRef, CellRef targetCellRef, Sheet sheet) {
Row row = sheet.getRow(targetCellRef.getRow());
if (row == null) {
row = sheet.createRow(targetCellRef.getRow());
}
return row;
}

protected void transformCell(CellRef srcCellRef, CellRef targetCellRef, Context context,
boolean updateRowHeightFlag, CellData cellData, Sheet destSheet, Row destRow) {
Expand Down Expand Up @@ -464,4 +479,9 @@ public void adjustTableSize(CellRef ref, Size size) {
}
}
}

@Override
public void setSheetCreator(SheetCreator sheetCreator) {
this.sheetCreator = sheetCreator;
}
}
35 changes: 0 additions & 35 deletions jxls-poi/src/main/java/org/jxls/transform/poi/PoiUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
Expand Down Expand Up @@ -43,40 +42,6 @@ public WritableCellValue hyperlink(String address, String title) {
return new WritableHyperlink(address, title);
}

public static void copySheetProperties(Sheet src, Sheet dest) {
dest.setAutobreaks(src.getAutobreaks());
dest.setDisplayGridlines(src.isDisplayGridlines());
dest.setVerticallyCenter(src.getVerticallyCenter());
dest.setFitToPage(src.getFitToPage());
dest.setForceFormulaRecalculation(src.getForceFormulaRecalculation());
dest.setRowSumsRight(src.getRowSumsRight());
dest.setRowSumsBelow(src.getRowSumsBelow());
copyPrintSetup(src, dest);
}

private static void copyPrintSetup(Sheet src, Sheet dest) {
PrintSetup srcPrintSetup = src.getPrintSetup();
PrintSetup destPrintSetup = dest.getPrintSetup();
destPrintSetup.setCopies(srcPrintSetup.getCopies());
destPrintSetup.setDraft(srcPrintSetup.getDraft());
destPrintSetup.setFitHeight(srcPrintSetup.getFitHeight());
destPrintSetup.setFitWidth(srcPrintSetup.getFitWidth());
destPrintSetup.setFooterMargin(srcPrintSetup.getFooterMargin());
destPrintSetup.setHeaderMargin(srcPrintSetup.getHeaderMargin());
destPrintSetup.setHResolution(srcPrintSetup.getHResolution());
destPrintSetup.setLandscape(srcPrintSetup.getLandscape());
destPrintSetup.setLeftToRight(srcPrintSetup.getLeftToRight());
destPrintSetup.setNoColor(srcPrintSetup.getNoColor());
destPrintSetup.setNoOrientation(srcPrintSetup.getNoOrientation());
destPrintSetup.setNotes(srcPrintSetup.getNotes());
destPrintSetup.setPageStart(srcPrintSetup.getPageStart());
destPrintSetup.setPaperSize(srcPrintSetup.getPaperSize());
destPrintSetup.setScale(srcPrintSetup.getScale());
destPrintSetup.setUsePage(srcPrintSetup.getUsePage());
destPrintSetup.setValidSettings(srcPrintSetup.getValidSettings());
destPrintSetup.setVResolution(srcPrintSetup.getVResolution());
}

public static boolean isJxComment(String cellComment) {
if (cellComment == null) return false;
String[] commentLines = cellComment.split("\\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.jxls.common.CellData;
import org.jxls.common.CellRef;
import org.jxls.common.Context;

/**
* You can use this PoiTransformer implementation to decide which worksheets use streaming.
Expand Down Expand Up @@ -39,39 +37,26 @@ public void setDataSheetsToUseStreaming(Set<String> sheetNames) {
}

@Override
public void transform(CellRef srcCellRef, CellRef targetCellRef, Context context, boolean updateRowHeightFlag) {
CellData cellData = isTransformable(srcCellRef, targetCellRef);
if (cellData == null) {
return;
}
Sheet destSheet = getWorkbook().getSheet(targetCellRef.getSheetName());
if (destSheet == null) {
destSheet = getWorkbook().createSheet(targetCellRef.getSheetName());
PoiUtil.copySheetProperties(getWorkbook().getSheet(srcCellRef.getSheetName()), destSheet);
}
protected Row getRow(CellRef srcCellRef, CellRef targetCellRef, Sheet sheet) {
boolean useStreamingForThisSheet = useStreaming(targetCellRef.getSheetName());
if (!useStreamingForThisSheet && isStreaming()) {
// use "fat" data sheet for transformation
destSheet = ((SXSSFWorkbook) getWorkbook()).getXSSFWorkbook().getSheet(targetCellRef.getSheetName());
sheet = ((SXSSFWorkbook) getWorkbook()).getXSSFWorkbook().getSheet(targetCellRef.getSheetName());
}
Row destRow = destSheet.getRow(targetCellRef.getRow());
if (destRow == null) {
Row row = sheet.getRow(targetCellRef.getRow());
if (row == null) {
if (useStreamingForThisSheet && isStreaming()) {
XSSFSheet _sh = ((SXSSFWorkbook) getWorkbook()).getXSSFWorkbook().getSheet(targetCellRef.getSheetName());
if (_sh.getPhysicalNumberOfRows() > 0 && targetCellRef.getRow() <= _sh.getLastRowNum()) {
destRow = _sh.getRow(targetCellRef.getRow());
destSheet = _sh;
if (destRow == null) {
destRow = destSheet.createRow(targetCellRef.getRow());
}
} else {
destRow = destSheet.createRow(targetCellRef.getRow());
row = _sh.getRow(targetCellRef.getRow());
sheet = _sh;
}
} else {
destRow = destSheet.createRow(targetCellRef.getRow());
}
if (row == null) { // yes, check again for null!
row = sheet.createRow(targetCellRef.getRow());
}
}
transformCell(srcCellRef, targetCellRef, context, updateRowHeightFlag, cellData, destSheet, destRow);
return row;
}

protected boolean useStreaming(String sheetName) {
Expand Down
3 changes: 2 additions & 1 deletion jxls-poi/src/test/java/org/jxls/TestWorkbook.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ public TestWorkbook(File file) {
* Following operations operate on the given sheet
* @param name exact visible name
*/
public void selectSheet(String name) {
public Sheet selectSheet(String name) {
sheet = workbook.getSheet(name);
if (sheet == null) {
throw new IllegalArgumentException("Sheet \"" + name + "\" does not exist!");
} else if (sheet instanceof XSSFSheet x
&& !SheetVisibility.VISIBLE.equals(workbook.getSheetVisibility(workbook.getSheetIndex(name)))) {
throw new IllegalArgumentException("Sheet \"" + name + "\" is not visible!");
}
return sheet;
}

/**
Expand Down
Loading

0 comments on commit 6dec5d3

Please sign in to comment.