{"id":464,"date":"2015-08-21T23:51:16","date_gmt":"2015-08-21T22:51:16","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=464"},"modified":"2015-08-24T19:53:57","modified_gmt":"2015-08-24T18:53:57","slug":"apache-poi-como-definir-estilos-en-archivos-excel","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/excel\/apache-poi-como-definir-estilos-en-archivos-excel\/","title":{"rendered":"Apache POI: C\u00f3mo definir estilos en archivos excel"},"content":{"rendered":"<p style=\"text-align: justify;\">En la entrada anterior sobre apache POI, vimos como <a href=\"http:\/\/www.pixnbgames.com\/blog\/java\/crear-archivos-excel-desde-java-con-apache-poi\/\">crear archivos excel con Java y Apache POI<\/a>. En esta ocasi\u00f3n, v\u00e9remos como personalizar el estilo de los archivos excel generados.<\/p>\n<h2 style=\"text-align: justify;\">C\u00f3mo crear un estilo de celda<\/h2>\n<p style=\"text-align: justify;\">La clase que representa un estilo de una celda es <code>HSSFCellStyle<\/code>. Nos permite definir caracter\u00edsticas propias de la celda: tipo de borde, color del borde, alineaci\u00f3n del contenido, color de fondo, etc. Para crear un estilo de celda, solo necesitamos una referencia al libro de trabajo de excel:<\/p>\n<pre lang=\"Java\">HSSFWorkbook workbook = new HSSFWorkbook();\r\nHSSFCellStyle style = workbook.createCellStyle();\r\n<\/pre>\n<p style=\"text-align: justify;\">Una vez creado el estilo, podemos invocar sus m\u00e9todos <code>set...()<\/code>, para configurar cada una de sus propiedades. La clase <code>HSSFCellStyle<\/code> posee una serie de propiedes definidas que nos ayudar\u00e1n a configurar nuestro estilo. As\u00ed mismo, la clase que nos permite definir los colores utilizados en nuestros estilos es <code>HSSFColor<\/code>:<\/p>\n<pre lang=\"Java\">\/\/ Sets the cell background\r\nstyle.setFillForegroundColor(HSSFColor.BLUE_GREY.index);\r\nstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);\r\n<\/pre>\n<p style=\"text-align: justify;\">Probablemente, tambi\u00e9n querremos modificar las propiedades del texto que se muestra en las celdas. Para hacer esto, debemos crear un estilo de fuente (a continuaci\u00f3n).<\/p>\n<h2 style=\"text-align: justify;\">C\u00f3mo crear un estilo de fuente<\/h2>\n<p style=\"text-align: justify;\">Los estilos de fuente est\u00e1 representados por la clase <code>HSSFFont<\/code>. Esta clase nos da control sobre la fuente tipogr\u00e1fica usada, color del texto, negrita, cursiva, etc. Al igual que los estilos de celdas, podemos crear estilos de fuentes a partir del libro de trabajo:<\/p>\n<pre lang=\"Java\">HSSFFont font = workbook.createFont();\r\n<\/pre>\n<p style=\"text-align: justify;\">Una vez tenemos la fuente, la asignamos al estilo donde queremos aplicarla:<\/p>\n<pre lang=\"Java\">style.setFont(font);<\/pre>\n<h1 style=\"text-align: justify;\"><\/h1>\n<h1 style=\"text-align: justify;\">Ejemplo Completo<\/h1>\n<p style=\"text-align: justify;\">Como ejemplo, vamos a generar un archivo excel tal que as\u00ed:<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/final_excel_with_style.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-480\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/final_excel_with_style.png\" alt=\"final_excel_with_style\" width=\"366\" height=\"432\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/final_excel_with_style.png 366w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/final_excel_with_style-254x300.png 254w\" sizes=\"(max-width: 366px) 100vw, 366px\" \/><\/a>Utilizaremos una clase auxiliar llamada <code>FakeDataProvider<\/code>, que simplemente nos devuelve de datos de prueba para rellenar la tabla:<\/p>\n<pre lang=\"Java\" line=\"11\">public final class FakeDataProvider {\r\n    \r\n    \/** Return the columns name for the table *\/\r\n    public static List<String> getTableHeaders() {\r\n        List<String> tableHeader = new ArrayList<String>();\r\n        tableHeader.add(\"Name\");\r\n        tableHeader.add(\"Address\");\r\n        tableHeader.add(\"Phone\");\r\n        \r\n        return tableHeader;\r\n    }\r\n\r\n    \r\n    \/**\r\n     * Return values for the table\r\n     * \r\n     * @param numberOfRows Number of rows we want to receive\r\n     * \r\n     * @return Values\r\n     *\/\r\n    public static List<List<String>> getTableContent(int numberOfRows) {\r\n        if (numberOfRows <= 0) {\r\n            throw new IllegalArgumentException(\"The number of rows must be a positive integer\");\r\n        }\r\n        \r\n        List<List<String>> tableContent = new ArrayList<List<String>>();\r\n\r\n        List<String> row = null;\r\n        for (int i = 0; i < numberOfRows; i++) {\r\n            tableContent.add(row = new ArrayList<String>());\r\n            row.add(\"my name is \" + i);\r\n            row.add(\"my address is \" + i);\r\n            row.add(\"my phone is \" + i);\r\n        }\r\n        \r\n        return tableContent;\r\n    }\r\n    \r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">La clase encargada de la generaci\u00f3n del excel es <code>ExcelGenerator<\/code>. Tiene un s\u00f3lo m\u00e9todo p\u00fablico, <code>generateExcel()<\/code>, que devuelve el excel generado:<\/p>\n<pre lang=\"Java\" line=\"15\">public class ExcelGenerator {\r\n\t\r\n\t\/\/ Excel work book\r\n\tprivate HSSFWorkbook workbook;\r\n\t\r\n\t\/\/ Fonts\r\n\tprivate HSSFFont headerFont;\r\n\tprivate HSSFFont contentFont;\r\n\t\r\n\t\/\/ Styles\r\n\tprivate HSSFCellStyle headerStyle;\r\n\tprivate HSSFCellStyle oddRowStyle;\r\n\tprivate HSSFCellStyle evenRowStyle;\r\n\t\r\n\t\/\/ Integer to store the index of the next row\r\n\tprivate int rowIndex;\r\n\t\r\n\r\n\t\/**\r\n\t * Make a new excel workbook with sheet that contains a stylized table\r\n\t * \r\n\t * @return\r\n\t *\/\r\n\tpublic HSSFWorkbook generateExcel() {\r\n\t\t\r\n\t\t\/\/ Initialize rowIndex\r\n\t\trowIndex = 0;\r\n\t\t\r\n\t\t\/\/ New Workbook\r\n\t\tworkbook = new HSSFWorkbook();\r\n\t\t\r\n\t\t\/\/ Generate fonts\r\n\t\theaderFont  = createFont(HSSFColor.WHITE.index, (short)12, true);\r\n\t\tcontentFont = createFont(HSSFColor.BLACK.index, (short)10, false);\r\n\t\t\r\n\t\t\/\/ Generate styles\r\n\t\theaderStyle  = createStyle(headerFont,  HSSFCellStyle.ALIGN_CENTER, HSSFColor.BLUE_GREY.index,       true, HSSFColor.WHITE.index);\r\n\t\toddRowStyle  = createStyle(contentFont, HSSFCellStyle.ALIGN_LEFT,   HSSFColor.GREY_25_PERCENT.index, true, HSSFColor.GREY_80_PERCENT.index);\r\n\t\tevenRowStyle = createStyle(contentFont, HSSFCellStyle.ALIGN_LEFT,   HSSFColor.GREY_40_PERCENT.index, true, HSSFColor.GREY_80_PERCENT.index);\r\n\t\t\r\n\t\t\/\/ New sheet\r\n\t\tHSSFSheet sheet = workbook.createSheet(\"Very Cool Sheet\");\r\n\t\t\r\n\t\t\/\/ Table header\r\n\t\tHSSFRow      headerRow    = sheet.createRow( rowIndex++ );\r\n\t\tList<String> headerValues = FakeDataProvider.getTableHeaders();\r\n\t\t\r\n\t\tHSSFCell headerCell = null;\r\n\t\tfor (int i = 0; i < headerValues.size(); i++) {\r\n\t\t\theaderCell = headerRow.createCell(i);\r\n\t\t\theaderCell.setCellStyle(headerStyle);\r\n\t\t\theaderCell.setCellValue( headerValues.get(i) );\r\n\t\t}\r\n\t\t\r\n\t\t\r\n\t\t\/\/ Table content\r\n\t\tHSSFRow  contentRow  = null;\r\n\t\tHSSFCell contentCell = null;\r\n\t\t\r\n\t\t\/\/ Obtain table content values\r\n\t\tList<List<String>> contentRowValues = FakeDataProvider.getTableContent(20);\r\n\t\tfor (List<String> rowValues : contentRowValues) {\r\n\t\t\t\r\n\t\t\t\/\/ At each row creation, rowIndex must grow one unit\r\n\t\t\tcontentRow = sheet.createRow( rowIndex++ );\r\n\t\t\tfor (int i = 0; i < rowValues.size(); i++) {\r\n\t\t\t\tcontentCell = contentRow.createCell(i);\r\n\t\t\t\tcontentCell.setCellValue( rowValues.get(i) );\r\n\t\t\t\t\r\n\t\t\t\t\/\/ Style depends on if row is odd or even\r\n\t\t\t\tcontentCell.setCellStyle( rowIndex % 2 == 0 ? oddRowStyle : evenRowStyle );\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t\r\n\t\t\/\/ Autosize columns\r\n\t\tfor (int i = 0; i < headerValues.size(); sheet.autoSizeColumn(i++));\r\n\t\t\r\n\t\treturn workbook;\r\n\t}\r\n\t\r\n\t\r\n\t\/**\r\n\t * Create a new font on base workbook\r\n\t * \r\n\t * @param fontColor       Font color (see {@link HSSFColor})\r\n\t * @param fontHeight      Font height in points\r\n\t * @param fontBold        Font is boldweight (<code>true<\/code>) or not (<code>false<\/code>)\r\n\t * \r\n\t * @return New cell style\r\n\t *\/\r\n\tprivate HSSFFont createFont(short fontColor, short fontHeight, boolean fontBold) {\r\n\t\t\r\n\t\tHSSFFont font = workbook.createFont();\r\n\t\tfont.setBold(fontBold);\r\n\t\tfont.setColor(fontColor);\r\n\t\tfont.setFontName(\"Arial\");\r\n\t\tfont.setFontHeightInPoints(fontHeight);\r\n\t\t\r\n\t\treturn font;\r\n\t}\r\n\t\r\n\t\r\n\t\/**\r\n\t * Create a style on base workbook\r\n\t * \r\n\t * @param font            Font used by the style\r\n\t * @param cellAlign       Cell alignment for contained text (see {@link HSSFCellStyle})\r\n\t * @param cellColor       Cell background color (see {@link HSSFColor})\r\n\t * @param cellBorder      Cell has border (<code>true<\/code>) or not (<code>false<\/code>)\r\n\t * @param cellBorderColor Cell border color (see {@link HSSFColor})\r\n\t * \r\n\t * @return New cell style\r\n\t *\/\r\n\tprivate HSSFCellStyle createStyle(HSSFFont font, short cellAlign, short cellColor, boolean cellBorder, short cellBorderColor) {\r\n\r\n\t\tHSSFCellStyle style = workbook.createCellStyle();\r\n\t\tstyle.setFont(font);\r\n\t\tstyle.setAlignment(cellAlign);\r\n\t\tstyle.setFillForegroundColor(cellColor);\r\n\t\tstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);\r\n\t\t\r\n\t\tif (cellBorder) {\r\n\t\t\tstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);\r\n\t\t\tstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);\r\n\t\t\tstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);\r\n\t\t\tstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);\r\n\t\t\t\r\n\t\t\tstyle.setTopBorderColor(cellBorderColor);\r\n\t\t\tstyle.setLeftBorderColor(cellBorderColor);\r\n\t\t\tstyle.setRightBorderColor(cellBorderColor);\r\n\t\t\tstyle.setBottomBorderColor(cellBorderColor);\r\n\t\t}\r\n\t\t\r\n\t\treturn style;\r\n\t}\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">Ya s\u00f3lo nos quedar\u00eda utilizarlo desde la clase principal y escribir el excel generado en disco:<\/p>\n<pre lang=\"Java\" line=\"11\">public class App {\r\n\r\n    public static void main(String[] args) {\r\n        \r\n        HSSFWorkbook workbook = new ExcelGenerator().generateExcel();\r\n        \r\n        \/\/ Writing the excel to output file\r\n        try {\r\n            OutputStream out = new FileOutputStream(\"src\/main\/resources\/ExcelWithStyles.xls\");\r\n            workbook.write(out);\r\n            workbook.close();\r\n            out.flush();\r\n            out.close();\r\n        }\r\n        catch (IOException e) {\r\n            System.err.println(\"Error at file writing\");\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<h2 style=\"text-align: justify;\"><\/h2>\n<h2 style=\"text-align: justify;\">Estilos con nombre<\/h2>\n<p style=\"text-align: justify;\">Si definimos un nombre de usuario para el estilo, \u00e9ste aparecer\u00e1 entre los estilos predefinidos al abrir el documento desde Microsoft Excel. Por ejemplo, si hubi\u00e9ramos hecho lo siguiente:<\/p>\n<pre lang=\"Java\">headerStyle.setUserStyleName(\"Header\");<\/pre>\n<p style=\"text-align: justify;\">Nuestro estilo estar\u00eda disponible para el usuario:<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/custom_user_styles.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-482\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/custom_user_styles.png\" alt=\"custom_user_styles\" width=\"651\" height=\"163\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/custom_user_styles.png 651w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/custom_user_styles-300x75.png 300w\" sizes=\"(max-width: 651px) 100vw, 651px\" \/><\/a><\/p>\n<h2 style=\"text-align: justify;\">Estilos sobre filas<\/h2>\n<p style=\"text-align: justify;\">Al igual que las celdas, las filas (<code>HSSFRow<\/code>) tienen un m\u00e9todo <code>setRowStyle()<\/code>. Es importante tener en cuenta que si aplicamos un estilo sobre una fila, \u00e9ste s\u00f3lo se aplica a las celdas vac\u00edas. Es decir, que en cuanto creemos una celda sobre esa fila invocando a s\u00fa m\u00e9todo <code>createCell()<\/code>, \u00e9sta no usar\u00e1 el estilo de la fila.<\/p>\n<h1 style=\"text-align: justify;\"><\/h1>\n<h1 style=\"text-align: justify;\">Optimizaci\u00f3n<\/h1>\n<p style=\"text-align: justify;\">Tanto los estilos (<code>HSSFCellStyle<\/code>) como las fuentes (<code>HSSFFont<\/code>) son creados a nivel de libro excel.<\/p>\n<p style=\"text-align: justify;\">Es necesario tenerlo en cuenta porque, si necesitamos aplicar un mismo estilo a varias celdas, lo correcto es crearlo una sola vez y aplicarlo a todas las celdas. Si en lugar de eso, creamos el estilo de nuevo cada vez que tenemos que aplicarlo a una celda, estaremos multiplicando el estilo tantas veces como celdas haya. Esto no es apreciable al mostrar el archivo excel generado, ya que todos los estilos son iguales, pero s\u00ed que tendremos un archivo generado de mayor tama\u00f1o.<\/p>\n<p style=\"text-align: justify;\">De igual forma, si queremos aplicar el mismo estilo de texto a varios estilos de celda, lo correcto es utilizar una misma fuente para todos los estilos, en lugar de crear una nueva fuente para cada estilo que la utilice.<\/p>\n<h1 style=\"text-align: justify;\"><\/h1>\n<h1 style=\"text-align: justify;\">C\u00f3digo fuente<\/h1>\n<p style=\"text-align: justify;\">Puedes descargar el proyecto de ejemplo <a href=\"https:\/\/github.com\/angelnavarro\/Apache-POI-Examples\" target=\"_blank\">mi repositorio de GitHub<\/a>. El ejemplo mostrado corresponde a <em>Poi-ExcelWithStyles<\/em>.<\/p>\n<p style=\"text-align: justify;\">Saludos,<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la entrada anterior sobre apache POI, vimos como crear archivos excel con Java y Apache POI. En esta ocasi\u00f3n, v\u00e9remos como personalizar el estilo de los archivos excel generados. C\u00f3mo crear un estilo de celda La clase que representa <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/excel\/apache-poi-como-definir-estilos-en-archivos-excel\/\">Seguir leyendo <span class=\"screen-reader-text\">  Apache POI: C\u00f3mo definir estilos en archivos excel<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[38,37],"tags":[40,41,39],"language":[5],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/464"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=464"}],"version-history":[{"count":15,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/464\/revisions"}],"predecessor-version":[{"id":490,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/464\/revisions\/490"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=464"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}