@SuppressWarnings("HardCodedStringLiteral") public class PdfDocumentWriter { private static final Log logger = LogFactory.getLog(PdfDocumentWriter.class); /** A useful constant for specifying the PDF creator. */ private static final String CREATOR = ClassicEngineInfo.getInstance().getName() + " version " + ClassicEngineInfo.getInstance().getVersion(); /** * A bytearray containing an empty password. iText replaces the owner password with random values, * but Adobe allows to have encryption without an owner password set. Copied from iText */ private static final byte[] PDF_PASSWORD_PAD = { (byte) 0x28, (byte) 0xBF, (byte) 0x4E, (byte) 0x5E, (byte) 0x4E, (byte) 0x75, (byte) 0x8A, (byte) 0x41, (byte) 0x64, (byte) 0x00, (byte) 0x4E, (byte) 0x56, (byte) 0xFF, (byte) 0xFA, (byte) 0x01, (byte) 0x08, (byte) 0x2E, (byte) 0x2E, (byte) 0x00, (byte) 0xB6, (byte) 0xD0, (byte) 0x68, (byte) 0x3E, (byte) 0x80, (byte) 0x2F, (byte) 0x0C, (byte) 0xA9, (byte) 0xFE, (byte) 0x64, (byte) 0x53, (byte) 0x69, (byte) 0x7A }; private Document document; private PdfOutputProcessorMetaData metaData; private OutputStream out; private PdfWriter writer; private boolean awaitOpenDocument; private Configuration config; private ResourceManager resourceManager; private LFUMap<ResourceKey, com.lowagie.text.Image> imageCache; private char version; public PdfDocumentWriter( final PdfOutputProcessorMetaData metaData, final OutputStream out, final ResourceManager resourceManager) { if (metaData == null) { throw new NullPointerException(); } if (out == null) { throw new NullPointerException(); } if (resourceManager == null) { throw new NullPointerException(); } this.imageCache = new LFUMap<ResourceKey, com.lowagie.text.Image>(50); this.resourceManager = resourceManager; this.metaData = metaData; this.out = out; this.config = metaData.getConfiguration(); } private Document getDocument() { return document; } public void open() throws DocumentException { this.document = new Document(); // pageSize, marginLeft, marginRight, marginTop, marginBottom)); writer = PdfWriter.getInstance(document, out); writer.setLinearPageMode(); version = getVersion(); writer.setPdfVersion(version); writer.setViewerPreferences(getViewerPreferences()); final String encrypt = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Encryption"); if (encrypt != null) { if (encrypt.equals(PdfPageableModule.SECURITY_ENCRYPTION_128BIT) == true || encrypt.equals(PdfPageableModule.SECURITY_ENCRYPTION_40BIT) == true) { final String userpassword = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.UserPassword"); final String ownerpassword = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.OwnerPassword"); // Log.debug ("UserPassword: "******" - OwnerPassword: "******"org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Title", config.getConfigProperty("org.pentaho.reporting.engine.classic.core.metadata.Title")); final String subject = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Description", config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.metadata.Description")); final String author = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Author", config.getConfigProperty("org.pentaho.reporting.engine.classic.core.metadata.Author")); final String keyWords = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Keywords", config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.metadata.Keywords")); if (title != null) { document.addTitle(title); } if (author != null) { document.addAuthor(author); } if (keyWords != null) { document.addKeywords(keyWords); } if (keyWords != null) { document.addSubject(subject); } document.addCreator(PdfDocumentWriter.CREATOR); document.addCreationDate(); // getDocument().open(); awaitOpenDocument = true; } /** * Extracts the Page Layout and page mode settings for this PDF (ViewerPreferences). All * preferences are defined as properties which have to be set before the target is opened. * * @return the ViewerPreferences. */ private int getViewerPreferences() { final String pageLayout = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PageLayout"); final String pageMode = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PageMode"); final String fullScreenMode = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.FullScreenMode"); final boolean hideToolBar = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideToolBar")); final boolean hideMenuBar = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideMenuBar")); final boolean hideWindowUI = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.HideWindowUI")); final boolean fitWindow = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.FitWindow")); final boolean centerWindow = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.CenterWindow")); final boolean displayDocTitle = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.DisplayDocTitle")); final boolean printScalingNone = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PrintScalingNone")); final String direction = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Direction"); int viewerPreferences = 0; if ("PageLayoutOneColumn".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutOneColumn; } else if ("PageLayoutSinglePage".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutSinglePage; } else if ("PageLayoutTwoColumnLeft".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutTwoColumnLeft; } else if ("PageLayoutTwoColumnRight".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutTwoColumnRight; } else if ("PageLayoutTwoPageLeft".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutTwoPageLeft; } else if ("PageLayoutTwoPageRight".equals(pageLayout)) { viewerPreferences = PdfWriter.PageLayoutTwoPageRight; } if ("PageModeUseNone".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeUseNone; } else if ("PageModeUseOutlines".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeUseOutlines; } else if ("PageModeUseThumbs".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeUseThumbs; } else if ("PageModeFullScreen".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeFullScreen; if ("NonFullScreenPageModeUseNone".equals(fullScreenMode)) { viewerPreferences = PdfWriter.NonFullScreenPageModeUseNone; } else if ("NonFullScreenPageModeUseOC".equals(fullScreenMode)) { viewerPreferences |= PdfWriter.NonFullScreenPageModeUseOC; } else if ("NonFullScreenPageModeUseOutlines".equals(fullScreenMode)) { viewerPreferences |= PdfWriter.NonFullScreenPageModeUseOutlines; } else if ("NonFullScreenPageModeUseThumbs".equals(fullScreenMode)) { viewerPreferences |= PdfWriter.NonFullScreenPageModeUseThumbs; } } else if ("PageModeUseOC".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeUseOC; } else if ("PageModeUseAttachments".equals(pageMode)) { viewerPreferences |= PdfWriter.PageModeUseAttachments; } if (hideToolBar) { viewerPreferences |= PdfWriter.HideToolbar; } if (hideMenuBar) { viewerPreferences |= PdfWriter.HideMenubar; } if (hideWindowUI) { viewerPreferences |= PdfWriter.HideWindowUI; } if (fitWindow) { viewerPreferences |= PdfWriter.FitWindow; } if (centerWindow) { viewerPreferences |= PdfWriter.CenterWindow; } if (displayDocTitle) { viewerPreferences |= PdfWriter.DisplayDocTitle; } if (printScalingNone) { viewerPreferences |= PdfWriter.PrintScalingNone; } if ("DirectionL2R".equals(direction)) { viewerPreferences |= PdfWriter.DirectionL2R; } else if ("DirectionR2L".equals(direction)) { viewerPreferences |= PdfWriter.DirectionR2L; } if (logger.isDebugEnabled()) { logger.debug("viewerPreferences = 0b" + Integer.toBinaryString(viewerPreferences)); } return viewerPreferences; } public void processPhysicalPage( final PageGrid pageGrid, final LogicalPageBox logicalPage, final int row, final int col, final PhysicalPageKey pageKey) throws DocumentException { final PhysicalPageBox page = pageGrid.getPage(row, col); if (page == null) { return; } final float width = (float) StrictGeomUtility.toExternalValue(page.getWidth()); final float height = (float) StrictGeomUtility.toExternalValue(page.getHeight()); final Rectangle pageSize = new Rectangle(width, height); final float marginLeft = (float) StrictGeomUtility.toExternalValue(page.getImageableX()); final float marginRight = (float) StrictGeomUtility.toExternalValue( page.getWidth() - page.getImageableWidth() - page.getImageableX()); final float marginTop = (float) StrictGeomUtility.toExternalValue(page.getImageableY()); final float marginBottom = (float) StrictGeomUtility.toExternalValue( page.getHeight() - page.getImageableHeight() - page.getImageableY()); final Document document = getDocument(); document.setPageSize(pageSize); document.setMargins(marginLeft, marginRight, marginTop, marginBottom); if (awaitOpenDocument) { document.open(); awaitOpenDocument = false; } final PdfContentByte directContent = writer.getDirectContent(); final Graphics2D graphics = new PdfGraphics2D(directContent, width, height, metaData); final PdfLogicalPageDrawable logicalPageDrawable = new PdfLogicalPageDrawable( logicalPage, metaData, writer, page, resourceManager, imageCache, version); final PhysicalPageDrawable drawable = new PhysicalPageDrawable(logicalPageDrawable, page); drawable.draw(graphics, new Rectangle2D.Double(0, 0, width, height)); graphics.dispose(); document.newPage(); } public void processLogicalPage(final LogicalPageKey key, final LogicalPageBox logicalPage) throws DocumentException { final float width = (float) StrictGeomUtility.toExternalValue(logicalPage.getPageWidth()); final float height = (float) StrictGeomUtility.toExternalValue(logicalPage.getPageHeight()); final Rectangle pageSize = new Rectangle(width, height); final Document document = getDocument(); document.setPageSize(pageSize); document.setMargins(0, 0, 0, 0); if (awaitOpenDocument) { document.open(); awaitOpenDocument = false; } final Graphics2D graphics = new PdfGraphics2D(writer.getDirectContent(), width, height, metaData); // and now process the box .. final PdfLogicalPageDrawable logicalPageDrawable = new PdfLogicalPageDrawable( logicalPage, metaData, writer, null, resourceManager, imageCache, version); logicalPageDrawable.draw(graphics, new Rectangle2D.Double(0, 0, width, height)); graphics.dispose(); document.newPage(); } /** Closes the document. */ public void close() { this.getDocument().close(); try { this.out.flush(); } catch (IOException e) { PdfDocumentWriter.logger.info("Flushing the PDF-Export-Stream failed."); } this.document = null; this.writer = null; } /** * Extracts the to be generated PDF version as iText parameter from the given property value. The * value has the form "1.x" where x is the extracted version. * * @return the itext character defining the version. */ private char getVersion() { final String version = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.Version"); if (version == null) { return '5'; } if (version.length() < 3) { PdfDocumentWriter.logger.warn( "PDF version specification is invalid, using default version '1.4'."); return '5'; } final char retval = version.charAt(2); if (retval < '2' || retval > '9') { PdfDocumentWriter.logger.warn( "PDF version specification is invalid, using default version '1.4'."); return '5'; } return retval; } /** * Extracts the permissions for this PDF. The permissions are returned as flags in the integer * value. All permissions are defined as properties which have to be set before the target is * opened. * * @return the permissions. */ private int getPermissions() { final String printLevel = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PrintLevel"); final boolean allowPrinting = "none".equals(printLevel) == false; final boolean allowDegradedPrinting = "degraded".equals(printLevel); final boolean allowModifyContents = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowModifyContents")); final boolean allowModifyAnn = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowModifyAnnotations")); final boolean allowCopy = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowCopy")); final boolean allowFillIn = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowFillIn")); final boolean allowScreenReaders = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowScreenReader")); final boolean allowAssembly = "true" .equals( config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.AllowAssembly")); int permissions = 0; if (allowPrinting) { permissions |= PdfWriter.ALLOW_PRINTING; } if (allowModifyContents) { permissions |= PdfWriter.ALLOW_MODIFY_CONTENTS; } if (allowModifyAnn) { permissions |= PdfWriter.ALLOW_MODIFY_ANNOTATIONS; } if (allowCopy) { permissions |= PdfWriter.ALLOW_COPY; } if (allowFillIn) { permissions |= PdfWriter.ALLOW_FILL_IN; } if (allowScreenReaders) { permissions |= PdfWriter.ALLOW_SCREENREADERS; } if (allowAssembly) { permissions |= PdfWriter.ALLOW_ASSEMBLY; } if (allowDegradedPrinting) { permissions |= PdfWriter.ALLOW_DEGRADED_PRINTING; } return permissions; } }
/** * Creation-Date: 09.05.2007, 14:52:05 * * @author Thomas Morgner */ public class RTFPrinter { private static final Log logger = LogFactory.getLog(RTFPrinter.class); private static final String CREATOR = ClassicEngineInfo.getInstance().getName() + " version " + ClassicEngineInfo.getInstance().getVersion(); private OutputStream outputStream; private Configuration config; private ResourceManager resourceManager; private RTFImageCache imageCache; private Document document; private Table table; private CellBackgroundProducer cellBackgroundProducer; public RTFPrinter() {} public void init( final Configuration config, final OutputStream outputStream, final ResourceManager resourceManager) { this.outputStream = outputStream; this.config = config; this.resourceManager = resourceManager; } /** @noinspection IOResourceOpenedButNotSafelyClosed */ public void print( final LogicalPageKey logicalPageKey, final LogicalPageBox logicalPage, final TableContentProducer contentProducer, final RTFOutputProcessorMetaData metaData, final boolean incremental) throws ContentProcessingException { final int startRow = contentProducer.getFinishedRows(); final int finishRow = contentProducer.getFilledRows(); if (incremental && startRow == finishRow) { return; } if (document == null) { this.cellBackgroundProducer = new CellBackgroundProducer( metaData.isFeatureSupported(AbstractTableOutputProcessor.TREAT_ELLIPSE_AS_RECTANGLE), metaData.isFeatureSupported(OutputProcessorFeature.UNALIGNED_PAGEBANDS)); final PhysicalPageBox pageFormat = logicalPage.getPageGrid().getPage(0, 0); final float urx = (float) StrictGeomUtility.toExternalValue(pageFormat.getWidth()); final float ury = (float) StrictGeomUtility.toExternalValue(pageFormat.getHeight()); final float marginLeft = (float) StrictGeomUtility.toExternalValue(pageFormat.getImageableX()); final float marginRight = (float) StrictGeomUtility.toExternalValue( pageFormat.getWidth() - pageFormat.getImageableWidth() - pageFormat.getImageableX()); final float marginTop = (float) StrictGeomUtility.toExternalValue(pageFormat.getImageableY()); final float marginBottom = (float) StrictGeomUtility.toExternalValue( pageFormat.getHeight() - pageFormat.getImageableHeight() - pageFormat.getImageableY()); final Rectangle pageSize = new Rectangle(urx, ury); document = new Document(pageSize, marginLeft, marginRight, marginTop, marginBottom); imageCache = new RTFImageCache(resourceManager); // rtf does not support PageFormats or other meta data... final PatchRtfWriter2 instance = PatchRtfWriter2.getInstance(document, new NoCloseOutputStream(outputStream)); instance.getDocumentSettings().setAlwaysUseUnicode(true); final String author = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.Author"); if (author != null) { document.addAuthor(author); } final String title = config.getConfigProperty( "org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.Title"); if (title != null) { document.addTitle(title); } document.addProducer(); document.addCreator(RTFPrinter.CREATOR); try { document.addCreationDate(); } catch (Exception e) { RTFPrinter.logger.debug("Unable to add creation date. It will have to work without it.", e); } document.open(); } // Start a new page. try { final SheetLayout sheetLayout = contentProducer.getSheetLayout(); final int columnCount = contentProducer.getColumnCount(); if (table == null) { final int rowCount = contentProducer.getRowCount(); table = new Table(columnCount, rowCount); table.setAutoFillEmptyCells(false); table.setWidth(100); // span the full page.. // and finally the content .. final float[] cellWidths = new float[columnCount]; for (int i = 0; i < columnCount; i++) { cellWidths[i] = (float) StrictGeomUtility.toExternalValue(sheetLayout.getCellWidth(i, i + 1)); } table.setWidths(cellWidths); } // logger.debug ("Processing: " + startRow + " " + finishRow + " " + incremental); for (int row = startRow; row < finishRow; row++) { for (short col = 0; col < columnCount; col++) { final RenderBox content = contentProducer.getContent(row, col); final CellMarker.SectionType sectionType = contentProducer.getSectionType(row, col); if (content == null) { final RenderBox backgroundBox = contentProducer.getBackground(row, col); final CellBackground background; if (backgroundBox != null) { background = cellBackgroundProducer.getBackgroundForBox( logicalPage, sheetLayout, col, row, 1, 1, true, sectionType, backgroundBox); } else { background = cellBackgroundProducer.getBackgroundAt( logicalPage, sheetLayout, col, row, true, sectionType); } if (background == null) { // An empty cell .. ignore final PatchRtfCell cell = new PatchRtfCell(); cell.setBorderWidth(0); cell.setMinimumHeight( (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row))); table.addCell(cell, row, col); continue; } // A empty cell with a defined background .. final PatchRtfCell cell = new PatchRtfCell(); cell.setBorderWidth(0); cell.setMinimumHeight( (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row))); updateCellStyle(cell, background); table.addCell(cell, row, col); continue; } if (content.isCommited() == false) { throw new InvalidReportStateException("Uncommited content encountered"); } final long contentOffset = contentProducer.getContentOffset(row, col); final long colPos = sheetLayout.getXPosition(col); final long rowPos = sheetLayout.getYPosition(row); if (content.getX() != colPos || (content.getY() + contentOffset) != rowPos) { // A spanned cell .. continue; } final int colSpan = sheetLayout.getColSpan(col, content.getX() + content.getWidth()); final int rowSpan = sheetLayout.getRowSpan(row, content.getY() + content.getHeight() + contentOffset); final CellBackground realBackground = cellBackgroundProducer.getBackgroundForBox( logicalPage, sheetLayout, col, row, colSpan, rowSpan, false, sectionType, content); final PatchRtfCell cell = new PatchRtfCell(); cell.setRowspan(rowSpan); cell.setColspan(colSpan); cell.setBorderWidth(0); cell.setMinimumHeight( (float) StrictGeomUtility.toExternalValue(sheetLayout.getRowHeight(row))); if (realBackground != null) { updateCellStyle(cell, realBackground); } computeCellStyle(content, cell); // export the cell and all content .. final RTFTextExtractor etx = new RTFTextExtractor(metaData); etx.compute(content, cell, imageCache); table.addCell(cell, row, col); content.setFinishedTable(true); // logger.debug("set Finished to cell (" + col + ", " + row + "," + content.getName() + // ")"); } } if (incremental == false) { document.add(table); table = null; } } catch (DocumentException e) { throw new ContentProcessingException("Failed to generate RTF-Document", e); } } private void computeCellStyle(final RenderBox content, final Cell cell) { final ElementAlignment verticalAlign = content.getNodeLayoutProperties().getVerticalAlignment(); if (ElementAlignment.BOTTOM.equals(verticalAlign)) { cell.setVerticalAlignment(Element.ALIGN_BOTTOM); } else if (ElementAlignment.MIDDLE.equals(verticalAlign)) { cell.setVerticalAlignment(Element.ALIGN_MIDDLE); } else { cell.setVerticalAlignment(Element.ALIGN_TOP); } final ElementAlignment textAlign = (ElementAlignment) content.getStyleSheet().getStyleProperty(ElementStyleKeys.ALIGNMENT); if (ElementAlignment.RIGHT.equals(textAlign)) { cell.setHorizontalAlignment(Element.ALIGN_RIGHT); } else if (ElementAlignment.JUSTIFY.equals(textAlign)) { cell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED); } else if (ElementAlignment.CENTER.equals(textAlign)) { cell.setHorizontalAlignment(Element.ALIGN_CENTER); } else { cell.setHorizontalAlignment(Element.ALIGN_LEFT); } } public void close() { if (document != null) { // cleanup.. document.close(); try { outputStream.flush(); } catch (IOException e) { RTFPrinter.logger.info("Failed to flush the RTF-Output stream."); } finally { document = null; } } } private int translateBorderStyle(final BorderStyle borderStyle) { if (BorderStyle.DASHED.equals(borderStyle)) { return RtfBorder.BORDER_DASHED; } if (BorderStyle.DOT_DASH.equals(borderStyle)) { return RtfBorder.BORDER_DOT_DASH; } if (BorderStyle.DOT_DOT_DASH.equals(borderStyle)) { return RtfBorder.BORDER_DOT_DOT_DASH; } if (BorderStyle.DOTTED.equals(borderStyle)) { return RtfBorder.BORDER_DOTTED; } if (BorderStyle.DOUBLE.equals(borderStyle)) { return RtfBorder.BORDER_DOUBLE; } if (BorderStyle.HIDDEN.equals(borderStyle)) { return RtfBorder.BORDER_NONE; } if (BorderStyle.NONE.equals(borderStyle)) { return RtfBorder.BORDER_NONE; } if (BorderStyle.GROOVE.equals(borderStyle)) { return RtfBorder.BORDER_ENGRAVE; } if (BorderStyle.RIDGE.equals(borderStyle)) { return RtfBorder.BORDER_EMBOSS; } if (BorderStyle.INSET.equals(borderStyle)) { return RtfBorder.BORDER_SINGLE; } if (BorderStyle.OUTSET.equals(borderStyle)) { return RtfBorder.BORDER_SINGLE; } if (BorderStyle.SOLID.equals(borderStyle)) { return RtfBorder.BORDER_SINGLE; } if (BorderStyle.WAVE.equals(borderStyle)) { return RtfBorder.BORDER_WAVY; } return RtfBorder.BORDER_NONE; } private void updateCellStyle(final Cell cell, final CellBackground background) { final Color backgroundColor = background.getBackgroundColor(); if (backgroundColor != null) { cell.setBackgroundColor(backgroundColor); } final BorderEdge top = background.getTop(); if (BorderEdge.EMPTY.equals(top) == false) { cell.setBorderColorTop(top.getColor()); cell.setBorderWidthTop((float) StrictGeomUtility.toExternalValue(top.getWidth())); } final BorderEdge left = background.getLeft(); if (BorderEdge.EMPTY.equals(left) == false) { cell.setBorderColorLeft(left.getColor()); cell.setBorderWidthLeft((float) StrictGeomUtility.toExternalValue(left.getWidth())); } final BorderEdge bottom = background.getBottom(); if (BorderEdge.EMPTY.equals(bottom) == false) { cell.setBorderColorBottom(bottom.getColor()); cell.setBorderWidthBottom((float) StrictGeomUtility.toExternalValue(bottom.getWidth())); } final BorderEdge right = background.getRight(); if (BorderEdge.EMPTY.equals(right) == false) { cell.setBorderColorRight(right.getColor()); cell.setBorderWidthRight((float) StrictGeomUtility.toExternalValue(right.getWidth())); } } }