KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > write > biff > SheetWriter


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.write.biff;
21
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.TreeSet JavaDoc;
26
27 import common.Assert;
28 import common.Logger;
29
30 import jxl.Cell;
31 import jxl.Range;
32 import jxl.SheetSettings;
33 import jxl.WorkbookSettings;
34 import jxl.write.WritableWorkbook;
35 import jxl.write.WritableCell;
36 import jxl.write.WritableHyperlink;
37 import jxl.write.WriteException;
38 import jxl.write.Blank;
39 import jxl.write.WritableCellFormat;
40 import jxl.format.CellFormat;
41 import jxl.format.Border;
42 import jxl.format.BorderLineStyle;
43 import jxl.format.Colour;
44 import jxl.biff.XFRecord;
45 import jxl.biff.WorkspaceInformationRecord;
46 import jxl.biff.CountryCode;
47 import jxl.biff.drawing.Chart;
48 import jxl.biff.drawing.SheetDrawingWriter;
49
50 /**
51  * Contains the functionality necessary for writing out a sheet. Originally
52  * this was incorporated in WritableSheetImpl, but was moved out into
53  * a dedicated class in order to reduce the over bloated nature of that
54  * class
55  */

56 final class SheetWriter
57 {
58   /**
59    * The logger
60    */

61   private static Logger logger = Logger.getLogger(SheetWriter.class);
62     
63   /**
64    * A handle to the output file which the binary data is written to
65    */

66   private File outputFile;
67
68   /**
69    * The rows within this sheet
70    */

71   private RowRecord[] rows;
72
73   /**
74    * A number of rows. This is a count of the maximum row number + 1
75    */

76   private int numRows;
77
78   /**
79    * The number of columns. This is a count of the maximum column number + 1
80    */

81   private int numCols;
82
83   /**
84    * The page header
85    */

86   private HeaderRecord header;
87   /**
88    * The page footer
89    */

90   private FooterRecord footer;
91   /**
92    * The settings for the sheet
93    */

94   private SheetSettings settings;
95   /**
96    * The settings for the workbook
97    */

98   private WorkbookSettings workbookSettings;
99   /**
100    * Array of row page breaks
101    */

102   private ArrayList JavaDoc rowBreaks;
103   /**
104    * Array of hyperlinks
105    */

106   private ArrayList JavaDoc hyperlinks;
107   /**
108    * The data validation validations
109    */

110   private DataValidation dataValidation;
111
112   /**
113    * The list of merged ranges
114    */

115   private MergedCells mergedCells;
116
117   /**
118    * The environment specific print record
119    */

120   private PLSRecord plsRecord;
121
122   /**
123    * The button property ste
124    */

125   private ButtonPropertySetRecord buttonPropertySet;
126
127   /**
128    * The workspace options
129    */

130   private WorkspaceInformationRecord workspaceOptions;
131   /**
132    * The column format overrides
133    */

134   private TreeSet JavaDoc columnFormats;
135
136   /**
137    * The list of drawings
138    */

139   private SheetDrawingWriter drawingWriter;
140
141   /**
142    * Flag indicates that this sheet contains just a chart, and nothing
143    * else
144    */

145   private boolean chartOnly;
146
147   /**
148    * A handle back to the writable sheet, in order for this class
149    * to invoke the get accessor methods
150    */

151   private WritableSheetImpl sheet;
152
153
154   /**
155    * Creates a new <code>SheetWriter</code> instance.
156    *
157    * @param of the output file
158    */

159   public SheetWriter(File of,
160                      WritableSheetImpl wsi,
161                      WorkbookSettings ws)
162   {
163     outputFile = of;
164     sheet = wsi;
165     workspaceOptions = new WorkspaceInformationRecord();
166     workbookSettings = ws;
167     chartOnly = false;
168     drawingWriter = new SheetDrawingWriter(ws);
169   }
170
171   /**
172    * Writes out this sheet. First writes out the standard sheet
173    * information then writes out each row in turn.
174    * Once all the rows have been written out, it retrospectively adjusts
175    * the offset references in the file
176    *
177    * @exception IOException
178    */

179   public void write() throws IOException JavaDoc
180   {
181     Assert.verify(rows != null);
182
183     // This worksheet consists of just one chart, so write it and return
184
if (chartOnly)
185     {
186       drawingWriter.write(outputFile);
187       return;
188     }
189
190     int bofpos = outputFile.getPos();
191
192     BOFRecord bof = new BOFRecord(BOFRecord.sheet);
193     outputFile.write(bof);
194
195     // Compute the number of blocks of 32 rows that will be needed
196
int numBlocks = numRows / 32;
197     if (numRows - numBlocks * 32 != 0)
198     {
199       numBlocks++;
200     }
201     
202     int indexPos = outputFile.getPos();
203    
204     // Write the index record out now in order to serve as a place holder
205
// The bof passed in is the bof of the workbook, not this sheet
206
IndexRecord indexRecord = new IndexRecord(0, numRows, numBlocks);
207     outputFile.write(indexRecord);
208
209     CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.automatic);
210     outputFile.write(cmr);
211
212     CalcCountRecord ccr = new CalcCountRecord(0x64);
213     outputFile.write(ccr);
214
215     RefModeRecord rmr = new RefModeRecord();
216     outputFile.write(rmr);
217     
218     IterationRecord itr = new IterationRecord(false);
219     outputFile.write(itr);
220
221     DeltaRecord dtr = new DeltaRecord(0.001);
222     outputFile.write(dtr);
223
224     SaveRecalcRecord srr = new SaveRecalcRecord(true);
225     outputFile.write(srr);
226
227     PrintHeadersRecord phr = new PrintHeadersRecord
228       (settings.getPrintHeaders());
229     outputFile.write(phr);
230
231     PrintGridLinesRecord pglr = new PrintGridLinesRecord
232       (settings.getPrintGridLines());
233     outputFile.write(pglr);
234
235     GridSetRecord gsr = new GridSetRecord(true);
236     outputFile.write(gsr);
237
238     GuttersRecord gutr = new GuttersRecord();
239     outputFile.write(gutr);
240
241     DefaultRowHeightRecord drhr = new DefaultRowHeightRecord
242      (settings.getDefaultRowHeight(),
243        settings.getDefaultRowHeight() != settings.DEFAULT_DEFAULT_ROW_HEIGHT);
244     outputFile.write(drhr);
245
246     workspaceOptions.setFitToPages(settings.getFitToPages());
247     outputFile.write(workspaceOptions);
248
249     if (rowBreaks.size() > 0)
250     {
251       int[] rb = new int[rowBreaks.size()];
252
253       for (int i = 0; i < rb.length; i++)
254       {
255         rb[i] = ( (Integer JavaDoc) rowBreaks.get(i)).intValue();
256       }
257
258       HorizontalPageBreaksRecord hpbr = new HorizontalPageBreaksRecord(rb);
259       outputFile.write(hpbr);
260     }
261
262     HeaderRecord header = new HeaderRecord(settings.getHeader().toString());
263     outputFile.write(header);
264
265     FooterRecord footer = new FooterRecord(settings.getFooter().toString());
266     outputFile.write(footer);
267
268     HorizontalCentreRecord hcr = new HorizontalCentreRecord(false);
269     outputFile.write(hcr);
270
271     VerticalCentreRecord vcr = new VerticalCentreRecord(false);
272     outputFile.write(vcr);
273
274     // Write out the margins if they don't equal the default
275
if (settings.getLeftMargin() != settings.getDefaultWidthMargin())
276     {
277       MarginRecord mr = new LeftMarginRecord(settings.getLeftMargin());
278       outputFile.write(mr);
279     }
280
281     if (settings.getRightMargin() != settings.getDefaultWidthMargin())
282     {
283       MarginRecord mr = new RightMarginRecord(settings.getRightMargin());
284       outputFile.write(mr);
285     }
286
287     if (settings.getTopMargin() != settings.getDefaultHeightMargin())
288     {
289       MarginRecord mr = new TopMarginRecord(settings.getTopMargin());
290       outputFile.write(mr);
291     }
292
293     if (settings.getBottomMargin() != settings.getDefaultHeightMargin())
294     {
295       MarginRecord mr = new BottomMarginRecord(settings.getBottomMargin());
296       outputFile.write(mr);
297     }
298
299     if (plsRecord != null)
300     {
301       outputFile.write(plsRecord);
302     }
303
304     SetupRecord setup = new SetupRecord(settings);
305     outputFile.write(setup);
306
307     if (settings.isProtected())
308     {
309       ProtectRecord pr = new ProtectRecord(settings.isProtected());
310       outputFile.write(pr);
311
312       ScenarioProtectRecord spr = new ScenarioProtectRecord
313         (settings.isProtected());
314       outputFile.write(spr);
315
316       ObjectProtectRecord opr = new ObjectProtectRecord
317         (settings.isProtected());
318       outputFile.write(opr);
319
320       if (settings.getPassword() != null)
321       {
322         PasswordRecord pw = new PasswordRecord(settings.getPassword());
323         outputFile.write(pw);
324       }
325       else if (settings.getPasswordHash() != 0)
326       {
327         PasswordRecord pw = new PasswordRecord(settings.getPasswordHash());
328         outputFile.write(pw);
329       }
330     }
331
332     indexRecord.setDataStartPosition(outputFile.getPos());
333     DefaultColumnWidth dcw =
334       new DefaultColumnWidth(settings.getDefaultColumnWidth());
335     outputFile.write(dcw);
336     
337     // Get a handle to the normal styles
338
WritableCellFormat normalStyle =
339       sheet.getWorkbook().getStyles().getNormalStyle();
340     WritableCellFormat defaultDateFormat =
341       sheet.getWorkbook().getStyles().getDefaultDateFormat();
342
343     // Write out all the column formats
344
ColumnInfoRecord cir = null;
345     int tmpi = 0;
346     for (Iterator JavaDoc colit = columnFormats.iterator(); colit.hasNext() ; )
347     {
348       cir = (ColumnInfoRecord) colit.next();
349
350       // Writing out the column info with index 0x100 causes excel to crash
351
if (cir.getColumn() < 0x100)
352       {
353         outputFile.write(cir);
354       }
355
356       XFRecord xfr = cir.getCellFormat();
357       
358       if (xfr != normalStyle && cir.getColumn() < 0x100)
359       {
360         // Make this the format for every cell in the column
361
Cell[] cells = getColumn(cir.getColumn());
362
363         for (int i = 0; i < cells.length; i++)
364         {
365           if (cells[i] != null &&
366               (cells[i].getCellFormat() == normalStyle ||
367                cells[i].getCellFormat() == defaultDateFormat))
368           {
369             // The cell has no overriding format specified, so
370
// set it to the column default
371
((WritableCell) cells[i]).setCellFormat(xfr);
372           }
373         }
374       }
375     }
376
377     DimensionRecord dr = new DimensionRecord(numRows, numCols);
378     outputFile.write(dr);
379
380     // Write out all the rows, in blocks of 32
381
for (int block = 0; block < numBlocks; block++)
382     {
383       DBCellRecord dbcell = new DBCellRecord(outputFile.getPos());
384
385       int blockRows = Math.min(32, numRows - block * 32);
386       boolean firstRow = true;
387
388       // First write out all the row records
389
for (int i = block * 32; i < block * 32 + blockRows; i++)
390       {
391         if (rows[i] != null)
392         {
393           rows[i].write(outputFile);
394           if (firstRow)
395           {
396             dbcell.setCellOffset(outputFile.getPos());
397             firstRow = false;
398           }
399         }
400       }
401
402       // Now write out all the cells
403
for (int i = block * 32; i < block * 32 + blockRows; i++)
404       {
405         if (rows[i] != null)
406         {
407           dbcell.addCellRowPosition(outputFile.getPos());
408           rows[i].writeCells(outputFile);
409         }
410       }
411
412       // Now set the current file position in the index record
413
indexRecord.addBlockPosition(outputFile.getPos());
414       
415       // Set the position of the file pointer and write out the DBCell
416
// record
417
dbcell.setPosition(outputFile.getPos());
418       outputFile.write(dbcell);
419     }
420     
421     // Write out the data validations
422
if (dataValidation != null)
423     {
424       dataValidation.write(outputFile);
425     }
426
427     // Do the drawings and charts if enabled
428
if (!workbookSettings.getDrawingsDisabled())
429     {
430       drawingWriter.write(outputFile);
431     }
432
433     Window2Record w2r = new Window2Record(settings);
434     outputFile.write(w2r);
435
436     // Handle the frozen panes
437
if (settings.getHorizontalFreeze() != 0 ||
438         settings.getVerticalFreeze() != 0)
439     {
440       PaneRecord pr = new PaneRecord(settings.getHorizontalFreeze(),
441                                      settings.getVerticalFreeze());
442       outputFile.write(pr);
443
444       // Handle the selection record. First, there will always be a top left
445
SelectionRecord sr = new SelectionRecord
446         (SelectionRecord.upperLeft, 0, 0);
447       outputFile.write(sr);
448
449       // Top right
450
if (settings.getHorizontalFreeze() != 0)
451       {
452         sr = new SelectionRecord
453           (SelectionRecord.upperRight, settings.getHorizontalFreeze(), 0);
454         outputFile.write(sr);
455       }
456
457       // Bottom left
458
if (settings.getVerticalFreeze() != 0)
459       {
460         sr = new SelectionRecord
461           (SelectionRecord.lowerLeft, 0, settings.getVerticalFreeze());
462         outputFile.write(sr);
463       }
464
465       // Bottom right
466
if (settings.getHorizontalFreeze() != 0 &&
467           settings.getVerticalFreeze() != 0)
468       {
469         sr = new SelectionRecord
470           (SelectionRecord.lowerRight,
471            settings.getHorizontalFreeze(),
472            settings.getVerticalFreeze());
473         outputFile.write(sr);
474       }
475
476       Weird1Record w1r = new Weird1Record();
477       outputFile.write(w1r);
478     }
479     else
480     {
481       // No frozen panes - just write out the selection record for the
482
// whole sheet
483
SelectionRecord sr = new SelectionRecord
484         (SelectionRecord.upperLeft, 0, 0);
485       outputFile.write(sr);
486     }
487
488     // Handle the zoom factor
489
if (settings.getZoomFactor() != 100)
490     {
491       SCLRecord sclr = new SCLRecord(settings.getZoomFactor());
492       outputFile.write(sclr);
493     }
494
495     // Now write out all the merged cells
496
mergedCells.write(outputFile);
497
498     // Write out all the hyperlinks
499
Iterator JavaDoc hi = hyperlinks.iterator();
500     WritableHyperlink hlr = null;
501     while (hi.hasNext())
502     {
503       hlr = (WritableHyperlink) hi.next();
504       outputFile.write(hlr);
505     }
506
507     if (buttonPropertySet != null)
508     {
509       outputFile.write(buttonPropertySet);
510     }
511
512
513     EOFRecord eof = new EOFRecord();
514     outputFile.write(eof);
515
516     // Now the various cross reference offsets have been calculated,
517
// retrospectively set the values in the output file
518
outputFile.setData(indexRecord.getData(), indexPos+4);
519   }
520
521   /**
522    * Gets the header. Called when copying sheets
523    *
524    * @return the page header
525    */

526   final HeaderRecord getHeader()
527   {
528     return header;
529   }
530
531   /**
532    * Gets the footer. Called when copying sheets
533    *
534    * @return the page footer
535    */

536   final FooterRecord getFooter()
537   {
538     return footer;
539   }
540
541   /**
542    * Sets the data necessary for writing out the sheet. This method must
543    * be called immediately prior to writing
544    *
545    * @param rws the rows in the spreadsheet
546    */

547   void setWriteData(RowRecord[] rws,
548                     ArrayList JavaDoc rb,
549                     ArrayList JavaDoc hl,
550                     MergedCells mc,
551                     TreeSet JavaDoc cf)
552   {
553     rows = rws;
554     rowBreaks = rb;
555     hyperlinks = hl;
556     mergedCells = mc;
557     columnFormats = cf;
558   }
559
560   /**
561    * Sets the dimensions of this spreadsheet. This method must be called
562    * immediately prior to writing
563    *
564    * @param rws the number of rows
565    * @param cls the number of columns
566    */

567   void setDimensions(int rws, int cls)
568   {
569     numRows = rws;
570     numCols = cls;
571   }
572
573   /**
574    * Sets the sheet settings for this particular sheet. Must be
575    * called immediately prior to writing
576    *
577    * @param sr the sheet settings
578    */

579   void setSettings(SheetSettings sr)
580   {
581     settings = sr;
582   }
583
584   /**
585    * Accessor for the workspace options
586    *
587    * @return the workspace options
588    */

589   WorkspaceInformationRecord getWorkspaceOptions()
590   {
591     return workspaceOptions;
592   }
593
594   /**
595    * Accessor for the workspace options
596    *
597    * @param wo the workspace options
598    */

599   void setWorkspaceOptions(WorkspaceInformationRecord wo)
600   {
601     workspaceOptions = wo;
602   }
603
604
605   /**
606    * Sets the charts for this sheet
607    *
608    * @param ch the charts
609    */

610   void setCharts(Chart[] ch)
611   {
612     drawingWriter.setCharts(ch);
613   }
614
615   /**
616    * Sets the drawings on this sheet
617    *
618    * @param dr the list of drawings
619    * @param mod a modified flag
620    */

621   void setDrawings(ArrayList JavaDoc dr, boolean mod)
622   {
623     drawingWriter.setDrawings(dr, mod);
624   }
625
626   /**
627    * Accessor for the charts on this sheet
628    *
629    * @return the charts
630    */

631   Chart[] getCharts()
632   {
633     return drawingWriter.getCharts();
634   }
635
636   /**
637    * Check all the merged cells for borders. If the merge record has
638    * borders, then we need to rejig the cell formats to take account of this.
639    * This is called by the write method of the WritableWorkbookImpl, so that
640    * any new XFRecords that are created may be written out with the others
641    */

642   void checkMergedBorders()
643   {
644     Range[] mcells = mergedCells.getMergedCells();
645     ArrayList JavaDoc borderFormats = new ArrayList JavaDoc();
646     for (int mci = 0 ; mci < mcells.length ; mci++)
647     {
648       Range range = mcells[mci];
649       Cell topLeft = range.getTopLeft();
650       XFRecord tlformat = (XFRecord) topLeft.getCellFormat();
651
652       if (tlformat != null &&
653           tlformat.hasBorders() == true &&
654           !tlformat.isRead())
655       {
656         try
657         {
658           CellXFRecord cf1 = new CellXFRecord(tlformat);
659           Cell bottomRight = range.getBottomRight();
660
661           cf1.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
662           cf1.setBorder(Border.LEFT,
663                         tlformat.getBorderLine(Border.LEFT),
664                         tlformat.getBorderColour(Border.LEFT));
665           cf1.setBorder(Border.TOP,
666                         tlformat.getBorderLine(Border.TOP),
667                         tlformat.getBorderColour(Border.TOP));
668
669           if (topLeft.getRow() == bottomRight.getRow())
670           {
671             cf1.setBorder(Border.BOTTOM,
672                           tlformat.getBorderLine(Border.BOTTOM),
673                           tlformat.getBorderColour(Border.BOTTOM));
674           }
675
676           if (topLeft.getColumn() == bottomRight.getColumn())
677           {
678             cf1.setBorder(Border.RIGHT,
679                           tlformat.getBorderLine(Border.RIGHT),
680                           tlformat.getBorderColour(Border.RIGHT));
681           }
682
683           int index = borderFormats.indexOf(cf1);
684           if (index != -1)
685           {
686             cf1 = (CellXFRecord) borderFormats.get(index);
687           }
688           else
689           {
690             borderFormats.add(cf1);
691           }
692           ( (WritableCell) topLeft).setCellFormat(cf1);
693
694           // Handle the bottom left corner
695
if (bottomRight.getRow() > topLeft.getRow())
696           {
697             // Handle the corner cell
698
if (bottomRight.getColumn() != topLeft.getColumn())
699             {
700               CellXFRecord cf2 = new CellXFRecord(tlformat);
701               cf2.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
702               cf2.setBorder(Border.LEFT,
703                             tlformat.getBorderLine(Border.LEFT),
704                             tlformat.getBorderColour(Border.LEFT));
705               cf2.setBorder(Border.BOTTOM,
706                             tlformat.getBorderLine(Border.BOTTOM),
707                             tlformat.getBorderColour(Border.BOTTOM));
708             
709               index = borderFormats.indexOf(cf2);
710               if (index != -1)
711               {
712                 cf2 = (CellXFRecord) borderFormats.get(index);
713               }
714               else
715               {
716                 borderFormats.add(cf2);
717               }
718
719               sheet.addCell(new Blank(topLeft.getColumn(),
720                                       bottomRight.getRow(), cf2));
721             }
722
723             // Handle the cells down the left hand side (and along the
724
// right too, if necessary)
725
for (int i = topLeft.getRow() + 1; i < bottomRight.getRow() ;i++)
726             {
727               CellXFRecord cf3 = new CellXFRecord(tlformat);
728               cf3.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
729               cf3.setBorder(Border.LEFT,
730                             tlformat.getBorderLine(Border.LEFT),
731                             tlformat.getBorderColour(Border.LEFT));
732
733               if (topLeft.getColumn() == bottomRight.getColumn())
734               {
735                 cf3.setBorder(Border.RIGHT,
736                               tlformat.getBorderLine(Border.RIGHT),
737                               tlformat.getBorderColour(Border.RIGHT));
738               }
739
740               index = borderFormats.indexOf(cf3);
741               if (index != -1)
742               {
743                 cf3 = (CellXFRecord) borderFormats.get(index);
744               }
745               else
746               {
747                 borderFormats.add(cf3);
748               }
749
750               sheet.addCell(new Blank(topLeft.getColumn(), i, cf3));
751             }
752           }
753
754           // Handle the top right corner
755
if (bottomRight.getColumn() > topLeft.getColumn())
756           {
757             if (bottomRight.getRow() != topLeft.getRow())
758             {
759               // Handle the corner cell
760
CellXFRecord cf6 = new CellXFRecord(tlformat);
761               cf6.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
762               cf6.setBorder(Border.RIGHT,
763                             tlformat.getBorderLine(Border.RIGHT),
764                             tlformat.getBorderColour(Border.RIGHT));
765               cf6.setBorder(Border.TOP,
766                             tlformat.getBorderLine(Border.TOP),
767                             tlformat.getBorderColour(Border.RIGHT));
768               index = borderFormats.indexOf(cf6);
769               if (index != -1)
770               {
771                 cf6 = (CellXFRecord) borderFormats.get(index);
772               }
773               else
774               {
775                 borderFormats.add(cf6);
776               }
777               
778               sheet.addCell(new Blank(bottomRight.getColumn(),
779                                       topLeft.getRow(), cf6));
780             }
781
782             // Handle the cells along the right
783
for (int i = topLeft.getRow() + 1;
784                      i < bottomRight.getRow() ;i++)
785             {
786               CellXFRecord cf7 = new CellXFRecord(tlformat);
787               cf7.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
788               cf7.setBorder(Border.RIGHT,
789                             tlformat.getBorderLine(Border.RIGHT),
790                             tlformat.getBorderColour(Border.RIGHT));
791
792               index = borderFormats.indexOf(cf7);
793               if (index != -1)
794               {
795                 cf7 = (CellXFRecord) borderFormats.get(index);
796               }
797               else
798               {
799                 borderFormats.add(cf7);
800               }
801               
802               sheet.addCell(new Blank(bottomRight.getColumn(), i, cf7));
803             }
804
805             // Handle the cells along the top, and along the bottom too
806
for (int i = topLeft.getColumn() + 1;
807                      i < bottomRight.getColumn() ;i++)
808             {
809               CellXFRecord cf8 = new CellXFRecord(tlformat);
810               cf8.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
811               cf8.setBorder(Border.TOP,
812                             tlformat.getBorderLine(Border.TOP),
813                             tlformat.getBorderColour(Border.TOP));
814               
815               if (topLeft.getRow() == bottomRight.getRow())
816               {
817                 cf8.setBorder(Border.BOTTOM,
818                               tlformat.getBorderLine(Border.BOTTOM),
819                               tlformat.getBorderColour(Border.BOTTOM));
820               }
821
822               index = borderFormats.indexOf(cf8);
823               if (index != -1)
824               {
825                 cf8 = (CellXFRecord) borderFormats.get(index);
826               }
827               else
828               {
829                 borderFormats.add(cf8);
830               }
831               
832               sheet.addCell(new Blank(i, topLeft.getRow(), cf8));
833             }
834           }
835
836           // Handle the bottom right corner
837
if (bottomRight.getColumn() > topLeft.getColumn() ||
838               bottomRight.getRow() > topLeft.getRow())
839           {
840             // Handle the corner cell
841
CellXFRecord cf4 = new CellXFRecord(tlformat);
842             cf4.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
843             cf4.setBorder(Border.RIGHT,
844                           tlformat.getBorderLine(Border.RIGHT),
845                           tlformat.getBorderColour(Border.RIGHT));
846             cf4.setBorder(Border.BOTTOM,
847                           tlformat.getBorderLine(Border.BOTTOM),
848                           tlformat.getBorderColour(Border.BOTTOM));
849
850             if (bottomRight.getRow() == topLeft.getRow())
851             {
852               cf4.setBorder(Border.TOP,
853                             tlformat.getBorderLine(Border.TOP),
854                             tlformat.getBorderColour(Border.TOP));
855             }
856
857             if (bottomRight.getColumn() == topLeft.getColumn())
858             {
859               cf4.setBorder(Border.LEFT,
860                             tlformat.getBorderLine(Border.LEFT),
861                             tlformat.getBorderColour(Border.LEFT));
862             }
863
864             index = borderFormats.indexOf(cf4);
865             if (index != -1)
866             {
867               cf4 = (CellXFRecord) borderFormats.get(index);
868             }
869             else
870             {
871               borderFormats.add(cf4);
872             }
873
874             sheet.addCell(new Blank(bottomRight.getColumn(),
875                                     bottomRight.getRow(), cf4));
876
877             // Handle the cells along the bottom (and along the top
878
// as well, if appropriate)
879
for (int i = topLeft.getColumn() + 1;
880                      i < bottomRight.getColumn() ;i++)
881             {
882               CellXFRecord cf5 = new CellXFRecord(tlformat);
883               cf5.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
884               cf5.setBorder(Border.BOTTOM,
885                             tlformat.getBorderLine(Border.BOTTOM),
886                             tlformat.getBorderColour(Border.BOTTOM));
887
888               if (topLeft.getRow() == bottomRight.getRow())
889               {
890                 cf5.setBorder(Border.TOP,
891                               tlformat.getBorderLine(Border.TOP),
892                               tlformat.getBorderColour(Border.TOP));
893               }
894
895               index = borderFormats.indexOf(cf5);
896               if (index != -1)
897               {
898                 cf5 = (CellXFRecord) borderFormats.get(index);
899               }
900               else
901               {
902                 borderFormats.add(cf5);
903               }
904               
905               sheet.addCell(new Blank(i, bottomRight.getRow(), cf5));
906             }
907           }
908         }
909         catch (WriteException e)
910         {
911           // just log e.toString(), not the whole stack trace
912
logger.warn(e.toString());
913         }
914       }
915     }
916   }
917
918   /**
919    * Get the cells in the column. Don't use the interface method
920    * getColumn for this as this will create loads of empty cells,
921    * and we could do without that overhead
922    */

923   private Cell[] getColumn(int col)
924   {
925     // Find the last non-null cell
926
boolean found = false;
927     int row = numRows - 1;
928
929     while (row >= 0 && !found)
930     {
931       if (rows[row] != null &&
932           rows[row].getCell(col) != null)
933       {
934         found = true;
935       }
936       else
937       {
938         row--;
939       }
940     }
941
942     // Only create entries for non-empty cells
943
Cell[] cells = new Cell[row+1];
944
945     for (int i = 0; i <= row; i++)
946     {
947       cells[i] = rows[i] != null ? rows[i].getCell(col) : null;
948     }
949
950     return cells;
951   }
952
953   /**
954    * Sets a flag to indicate that this sheet contains a chart only
955    */

956   void setChartOnly()
957   {
958     chartOnly = true;
959   }
960
961   /**
962    * Sets the environment specific print record
963    *
964    * @param pls the print record
965    */

966   void setPLS(PLSRecord pls)
967   {
968     plsRecord = pls;
969   }
970
971   /**
972    * Sets the button property set record
973    *
974    * @param bps the button property set
975    */

976   void setButtonPropertySet(ButtonPropertySetRecord bps)
977   {
978     buttonPropertySet = bps;
979   }
980
981   /**
982    * Sets the data validations
983    *
984    * @param dv the data validations
985    */

986   void setDataValidation(DataValidation dv)
987   {
988     dataValidation = dv;
989   }
990 }
991
Popular Tags