1. Contexte
Apache POI est une API Java qui crée et maintient diverses API Java conformes à la standard Office Open XML (OOXML) et au format de document composite OLE 2 de Microsoft (OLE2). Il peut être utilisé pour lire et créer et modifier les fichiers MS Excel à l'aide de Java. De plus, vous pouvez également utiliser Java pour lire et créer des fichiers MS Word et Mspowerpoint. Apache POI fournit une solution Java Operation Excel (pour Excel97-2008).
Générez le fichier Excel correspondant en fonction du fichier JSON au format spécifié. Les exigences sont les suivantes
2. Aperçu de l'effet
3. Format de données
Puisqu'il s'agit de générer un fichier Excel, la valeur ici considère la génération d'un fichier Excel au format xlsx. L'en-tête multi-table de données est considéré comme utilisé | Par défaut, et ColSpan Rowspan n'est pas utilisé comme. Si vous devez représenter deux colonnes et deux lignes, le premier format d'en-tête de fusion de colonne est: a | b, un tableau généré est
| UN | |
| B | C |
Le front-end construit les données à générer en tant que fichier JSON qui répond aux exigences et aux soumis et à l'arrière-plan via Post. Définissez le format JSON en fonction des exigences ci-dessus comme suit
{"Savename": "générer un nom de fichier Excel.xlsx", "UsersTyles": [{"id": "1", // pas de duplication, où vous devez définir le style de cellule, vous pouvez directement attribuer un style à cette valeur "Style": {"Font": {// Définir le format de la police "Where" Where "Where" Color ": // DoT it Bolde "# Ff0000", // couleur de police "nom": "Microsoft Elegant Black", // nom de police "hauteur": 20 // size}, "fmtstr": "", // format cellulaire, #, ## 0.00 _); #, ## 0.00; 0 Millimeters "Align": "", // ALIGNMENT HORIZONMENT En bas "BorderColor": "", // Définir la couleur de bord Informations "Data": [], // Données Informations "DataMerge": [], // Informations de fusion de données "Foot": [], // Table Information "FootMerge": [], // Table End Merge Information "IMG": [] // Informations d'image, vous devez convertir l'image en base64}]}Brève description
Le format d'objet JSON dans le tableau de tête est
{"Name": "A | B", // Nom de l'en-tête de table, Utilisation d'en-tête multi-table | Pour diviser "type": "str", // ce type de données de colonne str num, la date est également un type numérique dans Excel, et s'affiche sous forme de format de date "champ": "f_field1", // champs alternatifs, vous ne pouvez pas utiliser un "style": {// Cette colonne est le style de colonne par défaut, il peut être un objet de style, ou la valeur d'identification définie dans les utilisateurs " Dans le pied de données du titre du tableau, les données de la liste peuvent être une valeur distincte telle que 1, "A" ou un objet, lorsqu'il s'agit d'un objet, le format est
{"Value": "", // La valeur spécifique de la cellule "type": "", // le type de cellule, le style STR "par défaut": {} // Le style de cellule peut être un objet de style, ou la valeur d'ID définie dans UsersTyles. S'il n'est pas défini, la tête est le style correspondant de cette colonne par défaut} Les valeurs des tableaux Titlemerge, Datamerge et FootMerge sont des chaînes séparées des virgules, ce qui signifie "Start Row, End Row, Start Column, End Column", et que l'index commence à partir de 0. S'il y a deux lignes et trois colonnes de données dans le titre pour être "0, 0, 0, 1" "
La valeur dans le tableau IMG est un objet, format
{"Col": 1, // La colonne de démarrage de l'image "Row": 0, // La ligne de démarrage "Colspan": 1, // La portée de la colonne, la valeur minimale est de 1 "Rowspan": 2, // la portée de la ligne, la valeur minimale est de 1 "données": "" // base64 Données d'image telles que: "Data: Image / Png; Base64, ivbo ... ggg =="} 4. Implémentation clé
Les fichiers Excel après 07 sont en fait un package compressé, chaque feuille étant un fichier XML, chaque feuille étant un fichier XML, le style étant un fichier XML, l'image étant le fichier photo correspondant, et il est placé dans le dossier multimédia, donc l'idée de code est
Le portail de fonction est le suivant
@OverRidePublic void buildOutStstream () lève FileProduceRexception {// Processus des feuilles de données JSON entrantes = this.jsondata.getjsonArray (this.sheets); iterator <objet> sheetter = sheets.iterator (); if (sheets.isempty ()) {this.ResponSEdata.SetErterCode (1001); this.ResponseData.SetSuccess (false); this.ResponSEData.seTerrmsg ("Aucune donnée ne peut être générée"); lancez une nouvelle fileproducerexception ();} wb = new xssfworkbook (); // créer un format mondial jsonArray UsersTyles = this.jsondata.getjsonArray (this.userstyles); this.InitusersTyles (UsersTyles); this.initdefaultheadStyle (); XSSFSheet WS; Feuille JSONObject; JSONArray SheetData; JSONArray Sheettitle; JSONArray Sheethead; JSONArray sheetfoot; JSONArray SheetImgs; String sheetname; int sheetIndex = 0; while (sheetiter.hasnext ()) {sheet = (jsonObject) sheetter.next (); // obtenir le nom de feuille feuille de feuille = sheet.getString (this.sheet_name); ws = wb.createTheet (); if (strittUtils.isnotblank (sheetname)) {wb.SitSheetName (SheedIndEx, Shee sheetname);} int sheetrowindex = 0; sheettitle = sheet.getjsonArray (this.sheet_title); this.setMergecells (ws, sheet.getjsonArray (this.sheet_title_merge), sheetrowindex); sheetrowindex = this.createrandom (ws, sheettitle, sheetrowindex); sheethead = sheet.getjsonArray (this.sheet_head); sheetrowindex = this.CreateHeadColumn (ws, sheethead, sheetrowindex); this.setmergecells (ws, sheet.getjsonArray (this.sheet_data_merge), sheetrowindex); sheetdata = sheet.getjsonArray (this.sheet_data); sheetrowindex = this.createdata (ws, sheetdata, sheetrowindex); sheetfoot = sheet.getjsonArray (this.sheet_foot); this.setmergecells (ws, sheet.getjsonArray (this.sheet_foot_merge), sheetrowindex); sheetrowindex = this.createrandom (ws, sheetfoot, sheetrowindex); sheetImgs = sheet.getjsonArray (this.sheet_img); this.setSheetImages (ws, sheetImgs);} // return stream stream try {bytearrayoutputStream os = new bytearrayoutputStream (); wb.write (os); this.outStreams.add (os);} catch (ioException e) {throw new FileProduceReXception (e.getMessage (), e.getCause ());}}Générer des objets de style cellulaire, y compris l'alignement du fond des bordures de police
private xssfcellStyle createCellStyle (jsonObject style) {xssfcellStyle CellStyle = wb.createCellStyle (); // Set Font JsonObject Font = style.getjsonObject (this.style_font); Font Excrefont = this.createfont (Font); {cellstyle.setfont (exclfont);} // Unification de la bordure Black CellStyle.SetBorderBottom (Borderstyle.thin); CellStyle.SetBorderTop (Borderstyle.thin); CellStyle.Setborderleft (Borderstyle.thin); Cellstyle.SetborderRight (Borderstyle.Thin); Cellstyle.setborderright (Borderstyle.thin); String borderColor = style.getString (this.border_color); if (stringUtils.isnotblank (borderColor)) {xssfcolor xfborderColor = new XSSFColor (New Color (Integer.Parseint (BorderColor.SubStride. xfborderColor); cellstyle.setborderColor (borderside.top, xfborderColor); CellStyle.SetBorderColor (Borderside.left, xfborderColor); CellStyle.SetborderColor (Borderside.Right, xfborderColor);} // style.getString (this.background_color); if (stringUtils.isnotblank (bgcolor)) {xssfcolor cellbgcolor = new xssfcolor (new Color (Integer.Parseint (bgcolor.substring (1), 16))); CellStyle.setFillForeFrungColor (CellBgColor); CellStyle.SetFillPattern (FillPatterNype.solid_foreground);} // Alignment String Halignment = Style.getString (this.halignment); (StringUtils.isnotblank (halignment)) CellStyle.setalignment (horizontalalignment.valueof (halignment.toupperase ())); string valignment = style.getString (this.valignment); (StringUtils.isnotblank (valignment)) CellStyle.SetVerticalAlignment (VerticalAlignment.ValueOf (valignment.touppercase ())); // enveloppe automatique TRUECELLSTYLE.SetWrapText (true); // Format String fmt = style.getString (this.fmTString); if (stringUtils.isnotblank (fmt)) CellStyle.setDataFormat (wb.createdataformat (). getFormat (fmt)); return cellStyle;}Créer des styles de police
Private Font CreateFont (jsonObject Fontcfg) {if (fontcfg == null) return null; xssffont font = wb.createfont (); font.setfontname (fontcfg.getString (this.font_name)); Boolean Fontboole = Fontcfg.getBoolean (Font_Blod); Fontboole! NULL) FONT.SetBold (FontbooLe.BooleanValue ()); Fontboole = Fontcfg.getBoolean (this.font_italic); if (Fontboole! = null) font.setalic (Fontboole.BooleanValue (this.font_under); Fontboole = Fontcfg.getBoolean (this.font_under); (Fontboole! = null && fontboole.booleanValue () == true) font.setunderline (fontunderline.single.getByteValue ()); short fontheight = Fontcfg.getShort (this.font_height); if (Fontheight! = Null) font.setfontheightpoint Fontcfg.getString (this.font_color); if (colorestr! = null) {font.setColor (new XSSFColor (new Color (Integer.ParseInt (ColorStr.SubString (1), 16))));} RETOUR FONT;}Pour traiter les en-têtes de table, trop d'en-têtes de table sont traités et le | La méthode de segmentation est utilisée. La longueur de la tête est des données de colonne. Il y en a plusieurs | Dans le nom, et vous saurez combien de lignes il y a dans l'en-tête. Par conséquent, il existe plusieurs étapes pour le traitement des en-tête
private int CreateHeadColumn (XSSFSheet WS, JSONArray Sheethead, int sheetrowindex) {if (sheethead == null) return sheetrowindex; iterator <Object> Hentiterator = Sheethead.iterator (); jsonObject curhead = null; int colindex = 0; objet colstyle = null; int colSize = SheethEad.Size (); String [ColSize]; HeadCellSTyleKeys = new String [ColSize]; int [] headCoLevel = new int [ColSize]; String colname = null; String [] Colnameary = null; int maxLevel = 0; int Collevel = 0; XSSFCEll = newcell = null; ArrayList <ArrayList <String>> HeadValuList = new ArrayList <arrayList <string>> (); while (Hediter.Hasnext ()) {curhead = (jsonObject) Hediter.next (); // Gire Style par défaut if (curhead.containskey (this.column_style)) {colstyle = curhead.get (this.column_style); {HeadCellStyleKeys [Colindex] = this.columnstyle_prev + coLindex; this.userstyles.put (HeadCellStyleKeys [Colindex], this.createCellStyle ((jsonObject) Colstyle));} else if (this.userstyles.containskey (colstyle)) {headcellStylekey (curhead.containsKey (this.column_width)) {ws.SetDefaultColumnWidth (pixtoExcelWDith (curhead.getIntValue (this.column_width));} // Save Column Style if (curhead.containsKey) curhead.getString (this.column_type);} else {HeadTypes [colindex] = this.cellTypestring;} // gère la tête multi-table Colname = curhead.getString (this.column_name); ColnamEary = colinding; Collevel; if (Collevel> maxLevel) {maxLevel = Collevel;} pour (int i = 0; i <Collevel; i ++) {if (headValueList.Size () <= i) {HeadValueList.Add (new ArrayList <string> ());} HeadValuelList.get (i) .Add (Colindex, Colnamary [i]); ws.getrow (sheetrowindex + i); if (row == null) {row = ws.createrow (sheetrowindex + i);} headcell = row.createCell (colindex); headcell.setcellvalue (Colnameary [i]); headcell.setcellStyle (this.userstyles.get (this.headSyle_key);} colindex ++;} Iterator <arrayList <string >> a = headvalualist.iterator (); jsonArray headmerge = new JSONArray (); string prev = ""; string current = null; int lrowindex = 0; int startcol = 0; int megecol = 0; arrayList <string> columnInfo = null; while (a.hasnext ()) {startcol = 0; mergecol; while (a.hasnext () # = ""; chronninfo = a.next (); // uniquement dans la troisième colonne peut savoir si les première et deuxième colonnes sont fusionnées. ColumnInfo.Add (""); iterator <string> b = columninfo.iterator (); xssfCell lastrowCell = null; while (b.hasnext ()) {current = b.next (); if (lrowindex> 0) {lastrowcell = wsgetrow (sheetrowindex + lRowindex - 1). (prev.equalsignorecase (current) && lrowindex == 0) {ws.getrow (sheetrowindex + lrowindex) .getCell (startCol) .SetCellType (Cell.Cell_Type_Blank); MergeCol ++;} StringUtils.isblank (lastrowcell.getStringCellValue ())) {ws.GetRow (SheetrowIndex + Lrowindex) .GetCell (startCol) .SetCellType (Cell.Cell_Type_Blank); MergeCol ++;} Else {if (Mergecol> 0 && startCol> 0) {headmerge.add (string.format ("% d,% d,% d,% d", lrowindex, lrowindex, startcol - mergecol - 1, startCol - 1)); mergecol = 0;}} startCol ++; prev = current;} lrowindex ++;} pour (int i = 0; i <colSize; i ++) {pour (int i = 0; (HeadCollevel [i] <maxLevel) {// La fusion de la colonne existe HeadMerge.add (String.format ("% d,% d,% d,% d", headcollevel [i] - 1, maxlevel - 1, i, i)); for (int r = headcollevel [i]; r <maxlevel; r ++) {ws.GetRow (sheetrowex +; r) .CreateCell (i) .setCellStyle (this.userstyles.get (this.headStyle_key));}}} this.setMergells (ws, headmerge, sheetrowindex); retour sheetrowindex + maxlevel;};Ajoutez des images, les points de cellule sont utilisés par défaut et l'image est fixée dans la zone de cellule spécifiée.
private void addImg (xssfsheet ws, jsonObject img, xssfcreationhelper chelper) {string imgbase64 = img.getString (this.sheet_img_data); if (stringUtils.isblank (imgbase64)) return; string [] iMgary = imgbase64.split (","); system.out.println (imgary [0]); byte [] imgbyte = base64.decodeBase64 (imgary [1]); int imgidx = wb.addpicture (IMGBYTE, workbook.pictture_type_jpeg); ws.CreateDrawingPatriarch (); xssfclientanchor anchor = chelper.createClientanchor (); int col = img.getIntValue (this.sheet_img_col); int row = img.getIntValue (this.sheet_img_row); anchor.setCol1 (col); anchor.setrow1 (row); xssfpicture pict = drawimg.createepicture (anchor, imgidx); Integer Colspan = img.getInteger (this.sheet_img_colspan); if (Colspan) 1; Integer Rowspan = img.getInteger (this.sheet_img_rowspan); if (wowspan == null) rowspan = 1; pict.resize (colspan, wowspan);} 5. Résumé
Cette fois, j'ai généré un fichier Excel de style riche en passant dans des objets JSON, et je suis devenu plus familier avec les documents de l'Office Office POI. Par rapport aux documents Excel d'analyse, le format de fichier n'est pas nécessaire pour être pris en considération lors de la génération, tels que: compatible avec le format 2003, et l'analyse de saxophone de fichiers est considérée. Par rapport à la génération frontale JS de fichiers Excel, la possibilité de traitement secondaire des fichiers générés est augmentée, donc dans l'entrée fonctionnelle, la méthode de génération de flux binaires est adoptée. Une fois le fichier généré, vous pouvez continuer à envoyer des e-mails, télécharger FTP et d'autres opérations.
Notes clés
D'accord, ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.