You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestDrawingShapes.java 40KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hssf.model;
  16. import static org.apache.poi.hssf.usermodel.HSSFTestHelper.getEscherAggregate;
  17. import static org.junit.jupiter.api.Assertions.assertEquals;
  18. import static org.junit.jupiter.api.Assertions.assertFalse;
  19. import static org.junit.jupiter.api.Assertions.assertNotEquals;
  20. import static org.junit.jupiter.api.Assertions.assertNotNull;
  21. import static org.junit.jupiter.api.Assertions.assertNull;
  22. import static org.junit.jupiter.api.Assertions.assertSame;
  23. import static org.junit.jupiter.api.Assertions.assertTrue;
  24. import static org.junit.jupiter.api.Assertions.fail;
  25. import java.io.IOException;
  26. import java.util.Iterator;
  27. import java.util.List;
  28. import java.util.Spliterator;
  29. import org.apache.poi.ddf.EscherBoolProperty;
  30. import org.apache.poi.ddf.EscherContainerRecord;
  31. import org.apache.poi.ddf.EscherDgRecord;
  32. import org.apache.poi.ddf.EscherOptRecord;
  33. import org.apache.poi.ddf.EscherProperty;
  34. import org.apache.poi.ddf.EscherPropertyTypes;
  35. import org.apache.poi.ddf.EscherRecord;
  36. import org.apache.poi.ddf.EscherSimpleProperty;
  37. import org.apache.poi.ddf.EscherSpRecord;
  38. import org.apache.poi.ddf.EscherTextboxRecord;
  39. import org.apache.poi.hssf.HSSFTestDataSamples;
  40. import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
  41. import org.apache.poi.hssf.record.EscherAggregate;
  42. import org.apache.poi.hssf.record.ObjRecord;
  43. import org.apache.poi.hssf.usermodel.HSSFAnchor;
  44. import org.apache.poi.hssf.usermodel.HSSFChildAnchor;
  45. import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
  46. import org.apache.poi.hssf.usermodel.HSSFComment;
  47. import org.apache.poi.hssf.usermodel.HSSFPatriarch;
  48. import org.apache.poi.hssf.usermodel.HSSFPicture;
  49. import org.apache.poi.hssf.usermodel.HSSFPolygon;
  50. import org.apache.poi.hssf.usermodel.HSSFRichTextString;
  51. import org.apache.poi.hssf.usermodel.HSSFShape;
  52. import org.apache.poi.hssf.usermodel.HSSFShapeGroup;
  53. import org.apache.poi.hssf.usermodel.HSSFSheet;
  54. import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
  55. import org.apache.poi.hssf.usermodel.HSSFTestHelper;
  56. import org.apache.poi.hssf.usermodel.HSSFTextbox;
  57. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  58. import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
  59. import org.apache.poi.ss.usermodel.Workbook;
  60. import org.junit.jupiter.api.Test;
  61. /**
  62. * Test escher drawing
  63. *
  64. * optionally the system setting "poi.deserialize.escher" can be set to {@code true}
  65. */
  66. class TestDrawingShapes {
  67. /**
  68. * HSSFShape tree bust be built correctly
  69. * Check file with such records structure:
  70. * -patriarch
  71. * --shape
  72. * --group
  73. * ---group
  74. * ----shape
  75. * ----shape
  76. * ---shape
  77. * ---group
  78. * ----shape
  79. * ----shape
  80. */
  81. @Test
  82. void testDrawingGroups() throws IOException {
  83. try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) {
  84. HSSFSheet sheet = wb.getSheet("groups");
  85. HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
  86. assertEquals(2, patriarch.getChildren().size());
  87. HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);
  88. assertEquals(3, group.getChildren().size());
  89. HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);
  90. assertEquals(2, group1.getChildren().size());
  91. group1 = (HSSFShapeGroup) group.getChildren().get(2);
  92. assertEquals(2, group1.getChildren().size());
  93. }
  94. }
  95. @Test
  96. void testHSSFShapeCompatibility() {
  97. HSSFSimpleShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());
  98. shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  99. assertEquals(0x08000040, shape.getLineStyleColor());
  100. assertEquals(0x08000009, shape.getFillColor());
  101. assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());
  102. assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());
  103. assertFalse(shape.isNoFill());
  104. EscherOptRecord opt = shape.getOptRecord();
  105. assertEquals(7, opt.getEscherProperties().size());
  106. assertNotEquals(0, ((EscherSimpleProperty) opt.lookup(EscherPropertyTypes.GROUPSHAPE__FLAGS)).getPropertyValue());
  107. assertTrue(((EscherBoolProperty) opt.lookup(EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH)).isTrue());
  108. assertEquals(0x00000004, ((EscherSimpleProperty) opt.lookup(EscherPropertyTypes.GEOMETRY__SHAPEPATH)).getPropertyValue());
  109. assertNull(opt.lookup(EscherPropertyTypes.TEXT__SIZE_TEXT_TO_FIT_SHAPE));
  110. }
  111. @Test
  112. void testDefaultPictureSettings() {
  113. HSSFPicture picture = new HSSFPicture(null, new HSSFClientAnchor());
  114. assertEquals(HSSFShape.LINEWIDTH_DEFAULT, picture.getLineWidth());
  115. assertEquals(HSSFShape.FILL__FILLCOLOR_DEFAULT, picture.getFillColor());
  116. assertEquals(HSSFShape.LINESTYLE_NONE, picture.getLineStyle());
  117. assertEquals(HSSFShape.LINESTYLE__COLOR_DEFAULT, picture.getLineStyleColor());
  118. assertFalse(picture.isNoFill());
  119. // not set yet
  120. assertEquals(-1, picture.getPictureIndex());
  121. }
  122. /**
  123. * No NullPointerException should appear
  124. */
  125. @Test
  126. void testDefaultSettingsWithEmptyContainer() {
  127. EscherContainerRecord container = new EscherContainerRecord();
  128. EscherOptRecord opt = new EscherOptRecord();
  129. opt.setRecordId(EscherOptRecord.RECORD_ID);
  130. container.addChildRecord(opt);
  131. ObjRecord obj = new ObjRecord();
  132. CommonObjectDataSubRecord cod = new CommonObjectDataSubRecord();
  133. cod.setObjectType(HSSFSimpleShape.OBJECT_TYPE_PICTURE);
  134. obj.addSubRecord(cod);
  135. HSSFPicture picture = new HSSFPicture(container, obj);
  136. assertEquals(HSSFShape.LINEWIDTH_DEFAULT, picture.getLineWidth());
  137. assertEquals(HSSFShape.FILL__FILLCOLOR_DEFAULT, picture.getFillColor());
  138. assertEquals(HSSFShape.LINESTYLE_DEFAULT, picture.getLineStyle());
  139. assertEquals(HSSFShape.LINESTYLE__COLOR_DEFAULT, picture.getLineStyleColor());
  140. assertEquals(HSSFShape.NO_FILL_DEFAULT, picture.isNoFill());
  141. //not set yet
  142. assertEquals(-1, picture.getPictureIndex());
  143. }
  144. /**
  145. * create a rectangle, save the workbook, read back and verify that all shape properties are there
  146. */
  147. @Test
  148. void testReadWriteRectangle() throws IOException {
  149. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  150. HSSFSheet sheet = wb1.createSheet();
  151. HSSFPatriarch drawing = sheet.createDrawingPatriarch();
  152. HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 50, 50, (short) 2, 2, (short) 4, 4);
  153. anchor.setAnchorType(AnchorType.MOVE_DONT_RESIZE);
  154. assertEquals(AnchorType.MOVE_DONT_RESIZE, anchor.getAnchorType());
  155. anchor.setAnchorType(AnchorType.MOVE_DONT_RESIZE);
  156. assertEquals(AnchorType.MOVE_DONT_RESIZE, anchor.getAnchorType());
  157. HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
  158. rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  159. rectangle.setLineWidth(10000);
  160. rectangle.setFillColor(777);
  161. assertEquals(777, rectangle.getFillColor());
  162. assertEquals(10000, rectangle.getLineWidth());
  163. rectangle.setLineStyle(10);
  164. assertEquals(10, rectangle.getLineStyle());
  165. assertEquals(HSSFSimpleShape.WRAP_SQUARE, rectangle.getWrapText());
  166. rectangle.setLineStyleColor(1111);
  167. rectangle.setNoFill(true);
  168. rectangle.setWrapText(HSSFSimpleShape.WRAP_NONE);
  169. rectangle.setString(new HSSFRichTextString("teeeest"));
  170. assertEquals(1111, rectangle.getLineStyleColor());
  171. EscherContainerRecord escherContainer = HSSFTestHelper.getEscherContainer(rectangle);
  172. assertNotNull(escherContainer);
  173. EscherRecord childById = escherContainer.getChildById(EscherOptRecord.RECORD_ID);
  174. assertNotNull(childById);
  175. EscherProperty lookup = ((EscherOptRecord) childById).lookup(EscherPropertyTypes.TEXT__TEXTID);
  176. assertNotNull(lookup);
  177. assertEquals("teeeest".hashCode(), ((EscherSimpleProperty) lookup).getPropertyValue());
  178. assertTrue(rectangle.isNoFill());
  179. assertEquals(HSSFSimpleShape.WRAP_NONE, rectangle.getWrapText());
  180. assertEquals("teeeest", rectangle.getString().getString());
  181. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  182. sheet = wb2.getSheetAt(0);
  183. drawing = sheet.getDrawingPatriarch();
  184. assertEquals(1, drawing.getChildren().size());
  185. HSSFSimpleShape rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);
  186. assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
  187. assertEquals(10000, rectangle2.getLineWidth());
  188. assertEquals(10, rectangle2.getLineStyle());
  189. assertEquals(anchor, rectangle2.getAnchor());
  190. assertEquals(1111, rectangle2.getLineStyleColor());
  191. assertEquals(777, rectangle2.getFillColor());
  192. assertTrue(rectangle2.isNoFill());
  193. assertEquals("teeeest", rectangle2.getString().getString());
  194. assertEquals(HSSFSimpleShape.WRAP_NONE, rectangle.getWrapText());
  195. rectangle2.setFillColor(3333);
  196. rectangle2.setLineStyle(9);
  197. rectangle2.setLineStyleColor(4444);
  198. rectangle2.setNoFill(false);
  199. rectangle2.setLineWidth(77);
  200. rectangle2.getAnchor().setDx1(2);
  201. rectangle2.getAnchor().setDx2(3);
  202. rectangle2.getAnchor().setDy1(4);
  203. rectangle2.getAnchor().setDy2(5);
  204. rectangle.setWrapText(HSSFSimpleShape.WRAP_BY_POINTS);
  205. rectangle2.setString(new HSSFRichTextString("test22"));
  206. try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2)) {
  207. sheet = wb3.getSheetAt(0);
  208. drawing = sheet.getDrawingPatriarch();
  209. assertEquals(1, drawing.getChildren().size());
  210. rectangle2 = (HSSFSimpleShape) drawing.getChildren().get(0);
  211. assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
  212. assertEquals(HSSFSimpleShape.WRAP_BY_POINTS, rectangle.getWrapText());
  213. assertEquals(77, rectangle2.getLineWidth());
  214. assertEquals(9, rectangle2.getLineStyle());
  215. assertEquals(4444, rectangle2.getLineStyleColor());
  216. assertEquals(3333, rectangle2.getFillColor());
  217. assertEquals(2, rectangle2.getAnchor().getDx1());
  218. assertEquals(3, rectangle2.getAnchor().getDx2());
  219. assertEquals(4, rectangle2.getAnchor().getDy1());
  220. assertEquals(5, rectangle2.getAnchor().getDy2());
  221. assertFalse(rectangle2.isNoFill());
  222. assertEquals("test22", rectangle2.getString().getString());
  223. HSSFSimpleShape rect3 = drawing.createSimpleShape(new HSSFClientAnchor());
  224. rect3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  225. try (HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3)) {
  226. drawing = wb4.getSheetAt(0).getDrawingPatriarch();
  227. assertEquals(2, drawing.getChildren().size());
  228. }
  229. }
  230. }
  231. }
  232. }
  233. @Test
  234. void testReadExistingImage() throws IOException {
  235. try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) {
  236. HSSFSheet sheet = wb.getSheet("pictures");
  237. HSSFPatriarch drawing = sheet.getDrawingPatriarch();
  238. assertEquals(1, drawing.getChildren().size());
  239. HSSFPicture picture = (HSSFPicture) drawing.getChildren().get(0);
  240. assertEquals(2, picture.getPictureIndex());
  241. assertEquals(HSSFShape.LINESTYLE__COLOR_DEFAULT, picture.getLineStyleColor());
  242. assertEquals(0x5DC943, picture.getFillColor());
  243. assertEquals(HSSFShape.LINEWIDTH_DEFAULT, picture.getLineWidth());
  244. assertEquals(HSSFShape.LINESTYLE_DEFAULT, picture.getLineStyle());
  245. assertFalse(picture.isNoFill());
  246. picture.setPictureIndex(2);
  247. assertEquals(2, picture.getPictureIndex());
  248. }
  249. }
  250. /* assert shape properties when reading shapes from a existing workbook */
  251. @Test
  252. void testReadExistingRectangle() throws IOException {
  253. try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) {
  254. HSSFSheet sheet = wb.getSheet("rectangles");
  255. HSSFPatriarch drawing = sheet.getDrawingPatriarch();
  256. assertEquals(1, drawing.getChildren().size());
  257. HSSFSimpleShape shape = (HSSFSimpleShape) drawing.getChildren().get(0);
  258. assertFalse(shape.isNoFill());
  259. assertEquals(HSSFShape.LINESTYLE_DASHDOTGEL, shape.getLineStyle());
  260. assertEquals(0x616161, shape.getLineStyleColor());
  261. assertEquals(0x2CE03D, shape.getFillColor());
  262. assertEquals(HSSFShape.LINEWIDTH_ONE_PT * 2, shape.getLineWidth());
  263. assertEquals("POItest", shape.getString().getString());
  264. assertEquals(27, shape.getRotationDegree());
  265. }
  266. }
  267. @Test
  268. void testShapeIds() throws IOException {
  269. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  270. HSSFSheet sheet1 = wb1.createSheet();
  271. HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();
  272. for (int i = 0; i < 2; i++) {
  273. patriarch1.createSimpleShape(new HSSFClientAnchor());
  274. }
  275. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  276. sheet1 = wb2.getSheetAt(0);
  277. patriarch1 = sheet1.getDrawingPatriarch();
  278. EscherAggregate agg1 = getEscherAggregate(patriarch1);
  279. // last shape ID cached in EscherDgRecord
  280. EscherDgRecord dg1 = agg1.getEscherContainer().getChildById(EscherDgRecord.RECORD_ID);
  281. assertNotNull(dg1);
  282. assertEquals(1026, dg1.getLastMSOSPID());
  283. // iterate over shapes and check shapeId
  284. EscherContainerRecord spgrContainer =
  285. agg1.getEscherContainer().getChildContainers().get(0);
  286. // root spContainer + 2 spContainers for shapes
  287. assertEquals(3, spgrContainer.getChildCount());
  288. EscherSpRecord sp0 =
  289. ((EscherContainerRecord) spgrContainer.getChild(0)).getChildById(EscherSpRecord.RECORD_ID);
  290. assertNotNull(sp0);
  291. assertEquals(1024, sp0.getShapeId());
  292. EscherSpRecord sp1 =
  293. ((EscherContainerRecord) spgrContainer.getChild(1)).getChildById(EscherSpRecord.RECORD_ID);
  294. assertNotNull(sp1);
  295. assertEquals(1025, sp1.getShapeId());
  296. EscherSpRecord sp2 =
  297. ((EscherContainerRecord) spgrContainer.getChild(2)).getChildById(EscherSpRecord.RECORD_ID);
  298. assertNotNull(sp2);
  299. assertEquals(1026, sp2.getShapeId());
  300. }
  301. }
  302. }
  303. /**
  304. * Test get new id for shapes from existing file
  305. * File already have for 1 shape on each sheet, because document must contain EscherDgRecord for each sheet
  306. */
  307. @Test
  308. void testAllocateNewIds() throws IOException {
  309. try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("empty.xls")) {
  310. HSSFSheet sheet = wb.getSheetAt(0);
  311. HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
  312. // 2048 - main SpContainer id
  313. // 2049 - existing shape id
  314. assertEquals(2050, HSSFTestHelper.allocateNewShapeId(patriarch));
  315. assertEquals(2051, HSSFTestHelper.allocateNewShapeId(patriarch));
  316. assertEquals(2052, HSSFTestHelper.allocateNewShapeId(patriarch));
  317. sheet = wb.getSheetAt(1);
  318. patriarch = sheet.getDrawingPatriarch();
  319. // 3072 - main SpContainer id
  320. // 3073 - existing shape id
  321. assertEquals(3074, HSSFTestHelper.allocateNewShapeId(patriarch));
  322. assertEquals(3075, HSSFTestHelper.allocateNewShapeId(patriarch));
  323. assertEquals(3076, HSSFTestHelper.allocateNewShapeId(patriarch));
  324. sheet = wb.getSheetAt(2);
  325. patriarch = sheet.getDrawingPatriarch();
  326. assertEquals(1026, HSSFTestHelper.allocateNewShapeId(patriarch));
  327. assertEquals(1027, HSSFTestHelper.allocateNewShapeId(patriarch));
  328. assertEquals(1028, HSSFTestHelper.allocateNewShapeId(patriarch));
  329. }
  330. }
  331. @Test
  332. void testOpt() throws IOException {
  333. try (HSSFWorkbook wb = new HSSFWorkbook()) {
  334. // create a sheet with a text box
  335. HSSFSheet sheet = wb.createSheet();
  336. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  337. HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
  338. EscherOptRecord opt1 = HSSFTestHelper.getOptRecord(textbox);
  339. EscherOptRecord opt2 = HSSFTestHelper.getEscherContainer(textbox).getChildById(EscherOptRecord.RECORD_ID);
  340. assertSame(opt1, opt2);
  341. }
  342. }
  343. @Test
  344. void testCorrectOrderInOptRecord() throws IOException{
  345. try (HSSFWorkbook wb = new HSSFWorkbook()) {
  346. HSSFSheet sheet = wb.createSheet();
  347. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  348. HSSFTextbox textbox = patriarch.createTextbox(new HSSFClientAnchor());
  349. EscherOptRecord opt = HSSFTestHelper.getOptRecord(textbox);
  350. String opt1Str = opt.toXml();
  351. textbox.setFillColor(textbox.getFillColor());
  352. EscherContainerRecord container = HSSFTestHelper.getEscherContainer(textbox);
  353. EscherOptRecord optRecord = container.getChildById(EscherOptRecord.RECORD_ID);
  354. assertNotNull(optRecord);
  355. assertEquals(opt1Str, optRecord.toXml());
  356. textbox.setLineStyle(textbox.getLineStyle());
  357. assertEquals(opt1Str, optRecord.toXml());
  358. textbox.setLineWidth(textbox.getLineWidth());
  359. assertEquals(opt1Str, optRecord.toXml());
  360. textbox.setLineStyleColor(textbox.getLineStyleColor());
  361. assertEquals(opt1Str, optRecord.toXml());
  362. }
  363. }
  364. @Test
  365. void testDgRecordNumShapes() throws IOException {
  366. try (HSSFWorkbook wb = new HSSFWorkbook()) {
  367. HSSFSheet sheet = wb.createSheet();
  368. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  369. EscherAggregate aggregate = getEscherAggregate(patriarch);
  370. EscherDgRecord dgRecord = (EscherDgRecord) aggregate.getEscherRecord(0).getChild(0);
  371. assertEquals(1, dgRecord.getNumShapes());
  372. }
  373. }
  374. @Test
  375. void testTextForSimpleShape() throws IOException {
  376. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  377. HSSFSheet sheet = wb1.createSheet();
  378. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  379. HSSFSimpleShape shape = patriarch.createSimpleShape(new HSSFClientAnchor());
  380. shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  381. EscherAggregate agg = getEscherAggregate(patriarch);
  382. assertEquals(2, agg.getShapeToObjMapping().size());
  383. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  384. sheet = wb2.getSheetAt(0);
  385. patriarch = sheet.getDrawingPatriarch();
  386. shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
  387. agg = getEscherAggregate(patriarch);
  388. assertEquals(2, agg.getShapeToObjMapping().size());
  389. shape.setString(new HSSFRichTextString("string1"));
  390. assertEquals("string1", shape.getString().getString());
  391. assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
  392. assertEquals(2, agg.getShapeToObjMapping().size());
  393. try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2);
  394. HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3)) {
  395. sheet = wb4.getSheetAt(0);
  396. patriarch = sheet.getDrawingPatriarch();
  397. shape = (HSSFSimpleShape) patriarch.getChildren().get(0);
  398. assertNotNull(HSSFTestHelper.getTextObjRecord(shape));
  399. assertEquals("string1", shape.getString().getString());
  400. assertNotNull(HSSFTestHelper.getEscherContainer(shape).getChildById(EscherTextboxRecord.RECORD_ID));
  401. assertEquals(2, agg.getShapeToObjMapping().size());
  402. }
  403. }
  404. }
  405. }
  406. @Test
  407. void testRemoveShapes() throws IOException {
  408. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  409. HSSFSheet sheet1 = wb1.createSheet();
  410. HSSFPatriarch patriarch1 = sheet1.createDrawingPatriarch();
  411. HSSFSimpleShape rectangle = patriarch1.createSimpleShape(new HSSFClientAnchor());
  412. rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  413. int idx = wb1.addPicture(new byte[]{1, 2, 3}, Workbook.PICTURE_TYPE_JPEG);
  414. patriarch1.createPicture(new HSSFClientAnchor(), idx);
  415. patriarch1.createCellComment(new HSSFClientAnchor());
  416. HSSFPolygon polygon1 = patriarch1.createPolygon(new HSSFClientAnchor());
  417. polygon1.setPoints(new int[]{1, 2}, new int[]{2, 3});
  418. patriarch1.createTextbox(new HSSFClientAnchor());
  419. HSSFShapeGroup group1 = patriarch1.createGroup(new HSSFClientAnchor());
  420. group1.createTextbox(new HSSFChildAnchor());
  421. group1.createPicture(new HSSFChildAnchor(), idx);
  422. assertEquals(6, patriarch1.getChildren().size());
  423. assertEquals(2, group1.getChildren().size());
  424. assertEquals(12, getEscherAggregate(patriarch1).getShapeToObjMapping().size());
  425. assertEquals(1, getEscherAggregate(patriarch1).getTailRecords().size());
  426. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  427. HSSFSheet sheet2 = wb2.getSheetAt(0);
  428. HSSFPatriarch patriarch2 = sheet2.getDrawingPatriarch();
  429. assertEquals(12, getEscherAggregate(patriarch2).getShapeToObjMapping().size());
  430. assertEquals(1, getEscherAggregate(patriarch2).getTailRecords().size());
  431. assertEquals(6, patriarch2.getChildren().size());
  432. HSSFShapeGroup group2 = (HSSFShapeGroup) patriarch2.getChildren().get(5);
  433. group2.removeShape(group2.getChildren().get(0));
  434. assertEquals(10, getEscherAggregate(patriarch2).getShapeToObjMapping().size());
  435. assertEquals(1, getEscherAggregate(patriarch2).getTailRecords().size());
  436. try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2)) {
  437. HSSFSheet sheet3 = wb3.getSheetAt(0);
  438. HSSFPatriarch patriarch3 = sheet3.getDrawingPatriarch();
  439. assertEquals(10, getEscherAggregate(patriarch3).getShapeToObjMapping().size());
  440. assertEquals(1, getEscherAggregate(patriarch3).getTailRecords().size());
  441. HSSFShapeGroup group3 = (HSSFShapeGroup) patriarch3.getChildren().get(5);
  442. patriarch3.removeShape(group3);
  443. assertEquals(8, getEscherAggregate(patriarch3).getShapeToObjMapping().size());
  444. assertEquals(1, getEscherAggregate(patriarch3).getTailRecords().size());
  445. try (HSSFWorkbook wb4 = HSSFTestDataSamples.writeOutAndReadBack(wb3)) {
  446. HSSFSheet sheet4 = wb4.getSheetAt(0);
  447. HSSFPatriarch patriarch4 = sheet4.getDrawingPatriarch();
  448. assertEquals(8, getEscherAggregate(patriarch4).getShapeToObjMapping().size());
  449. assertEquals(1, getEscherAggregate(patriarch4).getTailRecords().size());
  450. assertEquals(5, patriarch4.getChildren().size());
  451. HSSFShape shape4 = patriarch4.getChildren().get(0);
  452. patriarch4.removeShape(shape4);
  453. assertEquals(6, getEscherAggregate(patriarch4).getShapeToObjMapping().size());
  454. assertEquals(1, getEscherAggregate(patriarch4).getTailRecords().size());
  455. assertEquals(4, patriarch4.getChildren().size());
  456. try (HSSFWorkbook wb5 = HSSFTestDataSamples.writeOutAndReadBack(wb4)) {
  457. HSSFSheet sheet5 = wb5.getSheetAt(0);
  458. HSSFPatriarch patriarch5 = sheet5.getDrawingPatriarch();
  459. assertEquals(6, getEscherAggregate(patriarch5).getShapeToObjMapping().size());
  460. assertEquals(1, getEscherAggregate(patriarch5).getTailRecords().size());
  461. assertEquals(4, patriarch5.getChildren().size());
  462. HSSFPicture picture5 = (HSSFPicture) patriarch5.getChildren().get(0);
  463. patriarch5.removeShape(picture5);
  464. assertEquals(5, getEscherAggregate(patriarch5).getShapeToObjMapping().size());
  465. assertEquals(1, getEscherAggregate(patriarch5).getTailRecords().size());
  466. assertEquals(3, patriarch5.getChildren().size());
  467. try (HSSFWorkbook wb6 = HSSFTestDataSamples.writeOutAndReadBack(wb5)) {
  468. HSSFSheet sheet6 = wb6.getSheetAt(0);
  469. HSSFPatriarch patriarch6 = sheet6.getDrawingPatriarch();
  470. assertEquals(5, getEscherAggregate(patriarch6).getShapeToObjMapping().size());
  471. assertEquals(1, getEscherAggregate(patriarch6).getTailRecords().size());
  472. assertEquals(3, patriarch6.getChildren().size());
  473. HSSFComment comment6 = (HSSFComment) patriarch6.getChildren().get(0);
  474. patriarch6.removeShape(comment6);
  475. assertEquals(3, getEscherAggregate(patriarch6).getShapeToObjMapping().size());
  476. assertEquals(0, getEscherAggregate(patriarch6).getTailRecords().size());
  477. assertEquals(2, patriarch6.getChildren().size());
  478. try (HSSFWorkbook wb7 = HSSFTestDataSamples.writeOutAndReadBack(wb6)) {
  479. HSSFSheet sheet7 = wb7.getSheetAt(0);
  480. HSSFPatriarch patriarch7 = sheet7.getDrawingPatriarch();
  481. assertEquals(3, getEscherAggregate(patriarch7).getShapeToObjMapping().size());
  482. assertEquals(0, getEscherAggregate(patriarch7).getTailRecords().size());
  483. assertEquals(2, patriarch7.getChildren().size());
  484. HSSFPolygon polygon7 = (HSSFPolygon) patriarch7.getChildren().get(0);
  485. patriarch7.removeShape(polygon7);
  486. assertEquals(2, getEscherAggregate(patriarch7).getShapeToObjMapping().size());
  487. assertEquals(0, getEscherAggregate(patriarch7).getTailRecords().size());
  488. assertEquals(1, patriarch7.getChildren().size());
  489. try (HSSFWorkbook wb8 = HSSFTestDataSamples.writeOutAndReadBack(wb7)) {
  490. HSSFSheet sheet8 = wb8.getSheetAt(0);
  491. HSSFPatriarch patriarch8 = sheet8.getDrawingPatriarch();
  492. assertEquals(2, getEscherAggregate(patriarch8).getShapeToObjMapping().size());
  493. assertEquals(0, getEscherAggregate(patriarch8).getTailRecords().size());
  494. assertEquals(1, patriarch8.getChildren().size());
  495. HSSFTextbox textbox8 = (HSSFTextbox) patriarch8.getChildren().get(0);
  496. patriarch8.removeShape(textbox8);
  497. assertEquals(0, getEscherAggregate(patriarch8).getShapeToObjMapping().size());
  498. assertEquals(0, getEscherAggregate(patriarch8).getTailRecords().size());
  499. assertEquals(0, patriarch8.getChildren().size());
  500. try (HSSFWorkbook wb9 = HSSFTestDataSamples.writeOutAndReadBack(wb8)) {
  501. HSSFSheet sheet9 = wb9.getSheetAt(0);
  502. HSSFPatriarch patriarch9 = sheet9.getDrawingPatriarch();
  503. assertEquals(0, getEscherAggregate(patriarch9).getShapeToObjMapping().size());
  504. assertEquals(0, getEscherAggregate(patriarch9).getTailRecords().size());
  505. assertEquals(0, patriarch9.getChildren().size());
  506. }
  507. }
  508. }
  509. }
  510. }
  511. }
  512. }
  513. }
  514. }
  515. }
  516. @Test
  517. void testShapeFlip() throws IOException {
  518. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  519. HSSFSheet sheet = wb1.createSheet();
  520. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  521. HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor());
  522. rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  523. assertFalse(rectangle.isFlipVertical());
  524. assertFalse(rectangle.isFlipHorizontal());
  525. rectangle.setFlipVertical(true);
  526. assertTrue(rectangle.isFlipVertical());
  527. rectangle.setFlipHorizontal(true);
  528. assertTrue(rectangle.isFlipHorizontal());
  529. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  530. sheet = wb2.getSheetAt(0);
  531. patriarch = sheet.getDrawingPatriarch();
  532. rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
  533. assertTrue(rectangle.isFlipHorizontal());
  534. rectangle.setFlipHorizontal(false);
  535. assertFalse(rectangle.isFlipHorizontal());
  536. assertTrue(rectangle.isFlipVertical());
  537. rectangle.setFlipVertical(false);
  538. assertFalse(rectangle.isFlipVertical());
  539. try (HSSFWorkbook wb3 = HSSFTestDataSamples.writeOutAndReadBack(wb2)) {
  540. sheet = wb3.getSheetAt(0);
  541. patriarch = sheet.getDrawingPatriarch();
  542. rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
  543. assertFalse(rectangle.isFlipVertical());
  544. assertFalse(rectangle.isFlipHorizontal());
  545. }
  546. }
  547. }
  548. }
  549. @Test
  550. void testRotation() throws IOException {
  551. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  552. HSSFSheet sheet = wb1.createSheet();
  553. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  554. HSSFSimpleShape rectangle = patriarch.createSimpleShape(new HSSFClientAnchor(0, 0, 100, 100, (short) 0, 0, (short) 5, 5));
  555. rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  556. assertEquals(0, rectangle.getRotationDegree());
  557. rectangle.setRotationDegree((short) 45);
  558. assertEquals(45, rectangle.getRotationDegree());
  559. rectangle.setFlipHorizontal(true);
  560. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  561. sheet = wb2.getSheetAt(0);
  562. patriarch = sheet.getDrawingPatriarch();
  563. rectangle = (HSSFSimpleShape) patriarch.getChildren().get(0);
  564. assertEquals(45, rectangle.getRotationDegree());
  565. rectangle.setRotationDegree((short) 30);
  566. assertEquals(30, rectangle.getRotationDegree());
  567. patriarch.setCoordinates(0, 0, 10, 10);
  568. rectangle.setString(new HSSFRichTextString("1234"));
  569. }
  570. }
  571. }
  572. @SuppressWarnings("unused")
  573. @Test
  574. void testShapeContainerImplementsIterable() throws IOException {
  575. try (HSSFWorkbook wb = new HSSFWorkbook()) {
  576. HSSFSheet sheet = wb.createSheet();
  577. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  578. HSSFSimpleShape s1 = patriarch.createSimpleShape(new HSSFClientAnchor());
  579. HSSFSimpleShape s2 = patriarch.createSimpleShape(new HSSFClientAnchor());
  580. Iterator<HSSFShape> iter = patriarch.iterator();
  581. assertEquals(s1, iter.next());
  582. assertEquals(s2, iter.next());
  583. assertFalse(iter.hasNext());
  584. Spliterator<HSSFShape> spliter = patriarch.spliterator();
  585. spliter.tryAdvance(s -> assertEquals(s1, s));
  586. spliter.tryAdvance(s -> assertEquals(s2, s));
  587. assertFalse(spliter.tryAdvance(s -> fail()));
  588. }
  589. }
  590. @Test
  591. void testClearShapesForPatriarch() throws IOException {
  592. try (HSSFWorkbook wb1 = new HSSFWorkbook()) {
  593. HSSFSheet sheet = wb1.createSheet();
  594. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  595. patriarch.createSimpleShape(new HSSFClientAnchor());
  596. patriarch.createSimpleShape(new HSSFClientAnchor());
  597. patriarch.createCellComment(new HSSFClientAnchor());
  598. EscherAggregate agg = getEscherAggregate(patriarch);
  599. assertEquals(6, agg.getShapeToObjMapping().size());
  600. assertEquals(1, agg.getTailRecords().size());
  601. assertEquals(3, patriarch.getChildren().size());
  602. patriarch.clear();
  603. assertEquals(0, agg.getShapeToObjMapping().size());
  604. assertEquals(0, agg.getTailRecords().size());
  605. assertEquals(0, patriarch.getChildren().size());
  606. try (HSSFWorkbook wb2 = HSSFTestDataSamples.writeOutAndReadBack(wb1)) {
  607. sheet = wb2.getSheetAt(0);
  608. patriarch = sheet.getDrawingPatriarch();
  609. assertEquals(0, agg.getShapeToObjMapping().size());
  610. assertEquals(0, agg.getTailRecords().size());
  611. assertEquals(0, patriarch.getChildren().size());
  612. }
  613. }
  614. }
  615. @Test
  616. void testBug45312() throws Exception {
  617. try (HSSFWorkbook wb = new HSSFWorkbook()) {
  618. HSSFSheet sheet = wb.createSheet();
  619. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  620. HSSFClientAnchor a1 = new HSSFClientAnchor();
  621. a1.setAnchor( (short)1, 1, 0, 0, (short) 1, 1, 512, 100);
  622. HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1);
  623. shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  624. HSSFClientAnchor a2 = new HSSFClientAnchor();
  625. a2.setAnchor( (short)1, 1, 512, 0, (short) 1, 1, 1024, 100);
  626. HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2);
  627. shape2.setFlipVertical(true);
  628. shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  629. HSSFClientAnchor a3 = new HSSFClientAnchor();
  630. a3.setAnchor( (short)2, 2, 0, 0, (short) 2, 2, 512, 100);
  631. HSSFSimpleShape shape3 = patriarch.createSimpleShape(a3);
  632. shape3.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  633. HSSFClientAnchor a4 = new HSSFClientAnchor();
  634. a4.setAnchor( (short)2, 2, 0, 100, (short) 2, 2, 512, 200);
  635. HSSFSimpleShape shape4 = patriarch.createSimpleShape(a4);
  636. shape4.setFlipHorizontal(true);
  637. shape4.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  638. checkWorkbookBack(wb);
  639. }
  640. }
  641. private void checkWorkbookBack(HSSFWorkbook wb) throws IOException {
  642. try (HSSFWorkbook wbBack = HSSFTestDataSamples.writeOutAndReadBack(wb)) {
  643. assertNotNull(wbBack);
  644. HSSFSheet sheetBack = wbBack.getSheetAt(0);
  645. assertNotNull(sheetBack);
  646. HSSFPatriarch patriarchBack = sheetBack.getDrawingPatriarch();
  647. assertNotNull(patriarchBack);
  648. List<HSSFShape> children = patriarchBack.getChildren();
  649. assertEquals(4, children.size());
  650. HSSFShape hssfShape = children.get(0);
  651. assertTrue(hssfShape instanceof HSSFSimpleShape);
  652. HSSFAnchor anchor = hssfShape.getAnchor();
  653. assertTrue(anchor instanceof HSSFClientAnchor);
  654. assertEquals(0, anchor.getDx1());
  655. assertEquals(512, anchor.getDx2());
  656. assertEquals(0, anchor.getDy1());
  657. assertEquals(100, anchor.getDy2());
  658. HSSFClientAnchor cAnchor = (HSSFClientAnchor) anchor;
  659. assertEquals(1, cAnchor.getCol1());
  660. assertEquals(1, cAnchor.getCol2());
  661. assertEquals(1, cAnchor.getRow1());
  662. assertEquals(1, cAnchor.getRow2());
  663. hssfShape = children.get(1);
  664. assertTrue(hssfShape instanceof HSSFSimpleShape);
  665. anchor = hssfShape.getAnchor();
  666. assertTrue(anchor instanceof HSSFClientAnchor);
  667. assertEquals(512, anchor.getDx1());
  668. assertEquals(1024, anchor.getDx2());
  669. assertEquals(0, anchor.getDy1());
  670. assertEquals(100, anchor.getDy2());
  671. cAnchor = (HSSFClientAnchor) anchor;
  672. assertEquals(1, cAnchor.getCol1());
  673. assertEquals(1, cAnchor.getCol2());
  674. assertEquals(1, cAnchor.getRow1());
  675. assertEquals(1, cAnchor.getRow2());
  676. hssfShape = children.get(2);
  677. assertTrue(hssfShape instanceof HSSFSimpleShape);
  678. anchor = hssfShape.getAnchor();
  679. assertTrue(anchor instanceof HSSFClientAnchor);
  680. assertEquals(0, anchor.getDx1());
  681. assertEquals(512, anchor.getDx2());
  682. assertEquals(0, anchor.getDy1());
  683. assertEquals(100, anchor.getDy2());
  684. cAnchor = (HSSFClientAnchor) anchor;
  685. assertEquals(2, cAnchor.getCol1());
  686. assertEquals(2, cAnchor.getCol2());
  687. assertEquals(2, cAnchor.getRow1());
  688. assertEquals(2, cAnchor.getRow2());
  689. hssfShape = children.get(3);
  690. assertTrue(hssfShape instanceof HSSFSimpleShape);
  691. anchor = hssfShape.getAnchor();
  692. assertTrue(anchor instanceof HSSFClientAnchor);
  693. assertEquals(0, anchor.getDx1());
  694. assertEquals(512, anchor.getDx2());
  695. assertEquals(100, anchor.getDy1());
  696. assertEquals(200, anchor.getDy2());
  697. cAnchor = (HSSFClientAnchor) anchor;
  698. assertEquals(2, cAnchor.getCol1());
  699. assertEquals(2, cAnchor.getCol2());
  700. assertEquals(2, cAnchor.getRow1());
  701. assertEquals(2, cAnchor.getRow2());
  702. }
  703. }
  704. }