From f9e5145d9ca9d092ab37486c5a0c065189d76421 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 9 Jan 2008 10:59:04 +0000 Subject: [PATCH] Add clone methods to DrawingRecord and AbstractEscherHolderRecord, which allows cloning of some sheets with drawing objects on them. Fixes bug #31795 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@610336 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 1 + src/documentation/content/xdocs/status.xml | 1 + .../record/AbstractEscherHolderRecord.java | 19 +++++++++++++++-- .../apache/poi/hssf/record/DrawingRecord.java | 17 ++++++++------- .../apache/poi/hssf/data/SheetWithDrawing.xls | Bin 0 -> 17408 bytes .../poi/hssf/usermodel/TestHSSFWorkbook.java | 20 ++++++++++++++++++ 6 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 src/testcases/org/apache/poi/hssf/data/SheetWithDrawing.xls diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 7a955b303..79eb0e914 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -36,6 +36,7 @@ + 31795 - Support cloning of sheets with certain drawing objects on them 43902 - Don't consider merged regions when auto-sizing columns 42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets 42033 - Add support for named ranges with unicode names diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 6c8b47b46..37383c816 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 31795 - Support cloning of sheets with certain drawing objects on them 43902 - Don't consider merged regions when auto-sizing columns 42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets 42033 - Add support for named ranges with unicode names diff --git a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java index efa83ca33..c9417a9c3 100644 --- a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java +++ b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java @@ -24,6 +24,9 @@ import org.apache.poi.ddf.EscherRecordFactory; import org.apache.poi.ddf.NullEscherSerializationListener; import org.apache.poi.util.LittleEndian; +import java.io.ByteArrayInputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -76,7 +79,7 @@ public abstract class AbstractEscherHolderRecord { if (id != getSid()) { - throw new RecordFormatException("Not an escher record"); + throw new RecordFormatException("Not an escher record! (sid was " + id + ", expecting " + getSid() + ")"); } } @@ -227,7 +230,19 @@ public abstract class AbstractEscherHolderRecord public Object clone() { - throw new IllegalStateException("Not implemented yet."); + // Do it via a re-serialise + // It's a cheat, but it works... + byte[] b = serialize(); + RecordInputStream rinp = new RecordInputStream( + new ByteArrayInputStream(b) + ); + rinp.nextRecord(); + + Record[] r = RecordFactory.createRecord(rinp); + if(r.length != 1) { + throw new IllegalStateException("Re-serialised a record to clone it, but got " + r.length + " records back!"); + } + return r[0]; } public void addEscherRecord(int index, EscherRecord element) diff --git a/src/java/org/apache/poi/hssf/record/DrawingRecord.java b/src/java/org/apache/poi/hssf/record/DrawingRecord.java index d6b34b6be..009bc31bc 100644 --- a/src/java/org/apache/poi/hssf/record/DrawingRecord.java +++ b/src/java/org/apache/poi/hssf/record/DrawingRecord.java @@ -107,15 +107,16 @@ public class DrawingRecord extends Record } public Object clone() { - if (recordData == null) { - recordData = new byte[ 0 ]; - } - DrawingRecord rec = new DrawingRecord(); - rec.recordData = new byte[ recordData.length ]; - rec.contd = new byte[ contd.length ]; - System.arraycopy(recordData, 0, rec.recordData, 0, recordData.length); - System.arraycopy(contd, 0, rec.contd, 0, contd.length); + + if (recordData != null) { + rec.recordData = new byte[ recordData.length ]; + System.arraycopy(recordData, 0, rec.recordData, 0, recordData.length); + } + if (contd != null) { + System.arraycopy(contd, 0, rec.contd, 0, contd.length); + rec.contd = new byte[ contd.length ]; + } return rec; } diff --git a/src/testcases/org/apache/poi/hssf/data/SheetWithDrawing.xls b/src/testcases/org/apache/poi/hssf/data/SheetWithDrawing.xls new file mode 100644 index 0000000000000000000000000000000000000000..e1395291b01b08e0100c1616c868bc30af681d7f GIT binary patch literal 17408 zcmeHP3sh9c8UF9G%Pyd>ECv-}Sx_TS#ne|M$||Cg9I4N!aa~r0C>2=?=s|pB@s*gP zM~$Y{n$##7F&d>bwpNX-t(+!Wwb4VYF;>(XQ-O4SW5jH~f0l&>CCBFUahlxOGc$Mo z`Cs$hxtE=PX8H4}z^X033b{lr(m?W}Z=62l?Ln7tZE&}>gnp-!o9;Rs*C5I1{|Ese z4Q`~jifR&0s6RI15;yr0DX3I=1SQdBWE0IMAEI3A)c9=cv?G+od0*333w@M!~mAl#!zJM=8;7h0JGy z(vw2yBk((4S;JEuNhJ-UT*{&;luiG+UcIsdsVImjvN*DHT<6XSiKck>rCu3^XRw1u z-=xu*8IwI3^rQwPjl$g%Jmt~SD?5{h^vyY1Xc26^DTWe=(%E>7L3olL@A9Ro+0Yvq zABn#7cw>6JUKvNx)Qtt3*i0VROmD_NfZ_3T)MT(1#ZnIsgKp^t z`)*NT)>AH&wo!Wk(Zz*xdUT>G%H1$U>y;6-okE-SyKrj86iM$=SQ8T)^VEYjtLjEO zD6%D23vCUoeW`?=!D!fu8^P$rhNdY>+z3-6fsy2fF&$RA(@tOyQBS!TgQt)S`$mZ* zdXM@yH|82ab9=%yw+}E06dP6ap zLq@{|BScFz?BU79Bd(&7@kl6^ar zCV%?HJ3cT0mFjiBfCdEl|aisG<0P7DfyEqk$QPiX1A|nXI?jLh^)NrU-$&KGL+Por z)qlEm*Sxjs`R8VCi-gi3&4M}h!~4zFpowMOzC0U&VOUBVdELUB!Sx5H-&@MC&bAb7@~+w1yZ@=b6zvP`&)_|`%09wt?tzj6 zQOB!SPX0Q!{eZ*a3|Y}@_V>N!RxD4+sOZAY@TcmQONn6@@85}UKOyO*4eD-8UB^s| zGOKTIK2vxuVMlw`SpNYu-u?LebSS~F^Up&1(5DG&FzoL#u6`r-14`+h&MYiFqa%HXIxYc~g6UHwY@ z)xAq@-(96QKRl3J{L96-*?~oV-ZgQ#7yKvRo3u9MsBriN)!{j#Hu=bj>aLe2) zS02oPYHf*+DNl9xliH)JYfSSiPsYr{RG6(Uirs5ZyLj-Y7ZMY{T61g+V71u~+28cK z`{~tN=a=N@Pi{_Dz}2b<#rVGtUf|T74KIK3*oi;9y8e19{#%d7}^U8@9do;CgSF4bqSU&Whq^u`wg2k=_g}?A+uE3WnCz1U0$gd6geJTH;kpDu;Uk&8%MDq7b`HQu@ zqL7zT@*46xFP@!J`@Y+g)6e}b8KEvpO-UQFXRu}QkI2uVL%SUN6B;U#u*sycOGcDN z(%-<@)E(lRFqpd_74t8 ze3;vvs*+q+T#o}U#-s3ecQ({D6e__#M>|9p;hTfU%zm=j0P=Fw<2rzpjwsX;`8b-7 z6htHi`3gD2OtHD-;y;SIOzEPFAppE&+=JIaR}Nwesw255%VAfda>PtEG#tAHCK^Ik znnrVI7G+Wns-`hf}^{YLC>8(Fj=g)zdeYq!8Z#4dPW5P7nFztT4dd8-g_ zZ<%=PRm(Qty#M1F+Fffk6x;3B=Mq5s09lR9{YGTqh$+Gog=hvcKh6t~@zBzGWIVw1 z4l=^xv>TZ%{S89cj-+7Z5n0o6t$Eg$^9{+?+}YOLDfwB}9MHL+(Qe#yrerJAc&aza zq!dic%ocvo`nrx$2M+SfgQ&9Nv^lLpYPgL|k&}#ojDU=QjDU=QjDU=QjDU=QjDU=Q zjDU>54;q1QTmLI6PgK6uy_0s`&$0fGyT6Cm{~SW%a15{iM3@g7XdK6}B2r_Z6mcLYm*(LPJ$VYo=@Ga0 zJdX_GH;wqszDvc>$7$kw?xv52^;{eankxL5=_WsMjsF7BXrKLfQo(0A1^fIA@$>Vf_Bm!I0%WLEj~uP~*Zk@C9mdbGI=B6Q E0;8K#+yDRo literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index 8a83abde6..6d5afca11 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -109,4 +109,24 @@ public class TestHSSFWorkbook extends TestCase assertEquals(b.getSelectedTab(), 1); assertEquals(b.getDisplayedTab(), 1); } + + public void testSheetClone() throws Exception { + // First up, try a simple file + HSSFWorkbook b = new HSSFWorkbook(); + assertEquals(0, b.getNumberOfSheets()); + b.createSheet("Sheet One"); + b.createSheet("Sheet Two"); + + assertEquals(2, b.getNumberOfSheets()); + b.cloneSheet(0); + assertEquals(3, b.getNumberOfSheets()); + + // Now try a problem one with drawing records in it + b = new HSSFWorkbook( + new FileInputStream(new File(filename,"SheetWithDrawing.xls")) + ); + assertEquals(1, b.getNumberOfSheets()); + b.cloneSheet(0); + assertEquals(2, b.getNumberOfSheets()); + } } \ No newline at end of file