@@ -0,0 +1,1421 @@
+package org.zkoss.zss.essential.util;%0A%0Aimport org.zkoss.zss.api.Ranges;%0Aimport org.zkoss.zss.api.model.Sheet;%0Aimport org.zkoss.zss.model.SName;%0A%0Aimport java.util.*;%0A%0A/**%0A * clone a sheet and its named ranges. A workaround for ZSS-1307.%0A */%0Apublic class SheetCopier %7B%0A%0A%0A%09/**%0A%09 * clone a sheet and its named ranges. %0A%09 */%0A%09public static Sheet clone(String sheetName, Sheet sourceSheet)%7B%0A%09%09Sheet targetSheet = Ranges.range(sourceSheet).cloneSheet(sheetName);%0A%09%09copyNamedRange(sourceSheet, targetSheet);%0A%09%09return targetSheet;%0A%09%7D%0A%0A%09/**%0A%09 * copy named ranges of source sheet to target sheet%0A%09 * @param sourceSheet%0A%09 * @param targetSheet%0A%09 */%0A%09private static void copyNamedRange(Sheet sourceSheet, Sheet targetSheet) %7B%0A%09%09List%3CSName%3E namedRangeList = new ArrayList%3CSName%3E(sourceSheet.getBook().getInternalBook().getNames()); //to avoid ConcurrentModificationException%0A%09%09for (SName definedName : namedRangeList)%7B%0A%09%09%09SName clonedNamedRange = null;%0A%09%09%09if (sourceSheet.getSheetName().equals(definedName.getRefersToSheetName()))%7B%0A%09%09%09%09clonedNamedRange = sourceSheet.getBook().getInternalBook().createName(definedName.getName(), targetSheet.getSheetName());%0A%09%09%09%09//shift formulas to the target sheet%0A%09%09%09%09String refersToFormula = definedName.getRefersToFormula();%0A%09%09%09%09refersToFormula = refersToFormula.replace(sourceSheet.getSheetName(), targetSheet.getSheetName());%0A%09%09%09%09clonedNamedRange.setRefersToFormula(refersToFormula);%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%7D

add a workaround for ZSS-1307 clone a sheet doesn't clone its named range