1. 배경
Apache Poi는 OOXML (Oxtml) 표준 및 Microsoft의 OLE 2 복합 문서 형식 (OLE2)을 준수하는 다양한 Java API를 생성하고 유지하는 Java API입니다. Java를 사용하여 MS Excel 파일을 읽고 생성하고 수정하는 데 사용할 수 있습니다. 또한 Java를 사용하여 MS Word 및 MspowerPoint 파일을 읽고 만들 수도 있습니다. Apache POI는 Java Operation Excel 솔루션 (Excel97-2008 용)을 제공합니다.
JSON 파일을 기반으로 해당 Excel 파일을 지정된 형식으로 생성하십시오. 요구 사항은 다음과 같습니다
2. 효과의 미리보기
3. 데이터 형식
Excel 파일을 생성하는 것이므로 여기의 값은 xlsx 형식으로 Excel 파일을 생성하는 것으로 간주합니다. 데이터 멀티 테이블 헤더는 사용되는 것으로 간주됩니다 기본적으로 Colspan rowspan은 사용하지 않습니다. 두 개의 열과 두 개의 행을 나타내야하는 경우 첫 번째 열은 헤더 형식을 합병합니다. a | b, a | c 생성 테이블은
| 에이 | |
| 비 | 기음 |
프론트 엔드는 데이터를 구축하여 요구 사항을 충족하고 게시물을 통해 제출 및 배경을 제출하는 JSON 파일로 생성됩니다. 위의 요구 사항에 따라 다음과 같이 JSON 형식 정의
{ "savename": "excel file name.xlsx 생성", "usertyles": [{ "id": "1", // 복제, 중복 없음, 셀 스타일을 설정 해야하는 곳,이 값 "스타일에 직접 스타일을 할당 할 수 있습니다. "#ff0000", // font color "name": "microsoft Elegant", // font name "height": 20 // size}, "fmtstr": "", // 셀 형식,#, ## 0.00 _); ## 0.00; 0 밀리 미터 "Align": "", // valignment center "", ",", "," ", // 하단 "BorderColor": "", // #ff0000 "bgcolor": ""// 셀 채우기 색상}}], "Sheets": [{ "sheetname": "", // 시트 이름 "제목": [], // compact 시트 제목 데이터 "titlemer": [], // compact sheet areate " 정보 "데이터": [], // 데이터 정보 "datamerge": [], // 데이터 병합 정보 "foot": [], // 테이블 엔드 정보 "footmerge": [], // 테이블 끝 정보 병합 정보 "IMG": [] // 그림을 base64}]}}}}}.간단한 설명
헤드 어레이의 JSON 객체 형식은 다음과 같습니다
{ "name": "a | b", // 테이블 헤더 이름, 멀티 테이블 헤더 사용 | "type": "str", //이 열 데이터 유형 str num, 날짜는 숫자 유형이며 날짜 형식 "필드": "f_field1", // 대체 필드로 표시됩니다. "스타일": {//이 열 데이터는 기본 객체 일 수 있거나, 스타일의 객체 또는 userstyles "align"}에서 정의 된 ID 값이 될 수 있습니다. 배열 제목 데이터 풋에서 목록의 데이터는 1, "a"또는 객체와 같은 별도의 값일 수 있습니다. 객체 일 때 형식은 다음과 같습니다.
{ "value": "", // 셀의 특정 값 "type": "", // 셀 유형, 기본 str "스타일": {} // 셀 스타일은 스타일 객체이거나 userstyles에 정의 된 ID 값이 될 수 있습니다. 설정되지 않은 경우 헤드는 기본적 으로이 열의 해당 스타일입니다} TitleMerge, Datamerge 및 Footmerge 어레이의 값은 쉼표로 구분 된 문자열입니다. 이는 "시작 행, 엔드로드, 시작 열, 끝 열"을 의미하며 인덱스는 0부터 시작됩니다. 제목에 두 개의 행과 3 개의 열이있는 경우 1 행의 해당 값과 두 열의 데이터 값을 "0, 0, 1, 1"으로 병합해야합니다.
IMG 배열의 값은 객체, 형식입니다.
{ "col": 1, // 그림 시작 열 "행": 0, // 시작 행 "colspan": 1, // 열 범위, 최소값은 1 "rowspan": 2, // 행 범위, 최소값은 1 "데이터": "// base64 그림 데이터 :"data : image/png; base64, ivbo ... ggg == " 4. 주요 구현
07 이후의 Excel 파일은 실제로 압축 패키지이며, 각 시트는 XML 파일, 스타일은 XML 파일, 그림은 해당 그림 파일이며 미디어 폴더에 배치되므로 코드 아이디어는 다음과 같습니다.
기능 포털은 다음과 같습니다
@OverRidePublic void buildOutputStream ()는 fileProduceEREXCeption을 던져 {// Process Incoming JSON Data Sheets = this.jsondata.getSonArray (this.sheets); iterator <boodge sheetiter = sheets.terator (); if (sheets.isempty ()); {this.responsedata.seterrcode (1001); this.responsedata.setsuccess (false); this.responsedata.seterrmsg ( "데이터가 생성 될 수 없음"); 새 FileProduceException ()을 던지는} wb = new xssfworkbook (); // 전역 형식 jsonarray usestyles = this.jsondata.getJsonArray (this.userstyles); this.inituserstyles (Userstyles); this.initDefaultheAdStyle (); xssfsheet ws; jsonobject 시트; JSONARRAY SETERDATA; JSONARRAY SHEETTITLE; Jsonarray Sheethead; JSONARRAY 시트 풋; JSONARRAY SETERIMGS; String sheetname; int sheetindex = 0; while (sheetter.hasnext ()) {sheet = (jsonobject) pheatre.next (); // 시트 이름 sheetname = sheet.getString (this.sheet_name); ws = wb.createsheet (if (stringUtils.isnotblank)) {wb.setname (setername) 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); 시트 풋 = 시트 .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 output stream try {bytearRayoutputStream os = new BytearRayoutputStream (); wb.write (os); this.outstreams.add (os);} catch (ioexception e) {새 FileProduceException 던지기 (e.getMessage (), e.getCause ());}}.글꼴 테두리 배경 정렬을 포함하여 셀 스타일 객체를 생성합니다
Private XSSFCellStyle CreateCellStyle (jsonObject 스타일) {XSSFCellStyle CellStyle = WB.CreateCellStyle (); // FONT JSONOBJECT FONT = Style.getJsonObject (this.Style_Font); Font ExcFelt = this.CreateFont (FONT); if); {CellStyle.setfont (Xcfelt);} // Border Unification Black Cellstyle.setborderbottom (Borderstyle.thin); Cellstyle.setbordertop (Borderstyle.thin); Cellstyle.setborderleft (Borderstyle.thin); Cellstyle.setborderright (Borderstyle.thin); Cellstyle.setborderright (Borderstyle.thin); String BortleColor = style.getString (this.border_color); if (stringUtils.isnotblank (BorderColor)) {xssfcolor xfbordercolor = new xssfcolor (new color (integer.parseint (1), 16)); XFBORDERCOLOR); CellStyle.setborderColor (Borderside.Top, XfborderColor); CellStyle.setborderColor (Borderside.Left, XfborderColor); CellStyle.setborderColor (Borderside.right, XFBORDERCOLOR);} // BAUR style.getString (this.background_color); if (stringUtils.isnotblank (bgcolor)) {xssfcolor cellbgcolor = new xssfcolor (new color (integer.sparseint (bgcolor.substring (1)), 16))); CellStyle.SetFillForeGroun (StringUtils.isnotblank (Halignment)) CellStyle.setAlignment (HorizontalAlignment.valueof (Halignment.toupperCase ())); String valignment = style.getString (this.valignment); if (StringUtils.isnotblank (Valignment)) CellStyle.setverticalAlignment (verticalAignment.valueof (valignment.toupperCase ())); // 자동 라인 랩 truecellstyle.setWrapText (true); // 형식 문자열 fmt = style.getString (this.fmtstring); if (stringUtils.isnotblank (fmt)) cellstyle.setDataformat (wb.createdataformat (). getformat (fmt)); return cellstyle;}글꼴 스타일을 만듭니다
private font createfont (jsonobject fontcfg) {if (fontcfg == null) return null; xsffont font = wb.createfont (); font.setfontname (fontcfg.getString (this.font_name)); boolean fontboole = fontcfg.getblean! if (font_blod); null) font.setBold (fontBoole.booleanValue ()); fontBoole = fontcfg.getBoolean (this.font_italic); if (fontboole! = null) font.setitalic (fontboole.booleanValue ()); fontboole = fontcfg.getBeale (this.fontcfg.getboole); (fontboole! = null && fontboole.booleanValue () == true) font.setunderline (fontunderline.single.getByteValue ()); short fontheight = fontcfg.getShort (this.font_height); if (fontheight! = null) font.setfon (fontinpon); fontcfg.getString (this.font_color); if (colorttr! = null) {font.setColor (new color (new color (integer.parseint (colorstr.substring (1), 16));} return font;}테이블 헤더를 처리하기 위해 너무 많은 테이블 헤더가 처리되고 | 세분화 방법이 사용됩니다. 헤드 길이는 열 데이터입니다. 몇 가지 | 그 이름으로, 당신은 헤더에 얼마나 많은 행이 있는지 알게 될 것입니다. 따라서 헤더 처리를위한 몇 가지 단계가 있습니다
Private int CreateHeadColumn (XSSFSHEET WS, JSONARRAY SHEETHEAD, int SHEETHEAD) {if (sheetHead == null) return sheetRowIndex; iterator <boter> headiterator = sheethead.iterator (); 문자열 [colsize]; headcellstylekeys = new String [colsize]; int [] headcollevel = new int [colsize]; String colname = null; String [] colnameary = null; int maxlevel = 0; int Collevel = 0; xssfcell headcell = null; arraylist <arraylist <string>> new headvaluel ist = ArrayList <ArrayList <String >> (); while (headiter.hasnext ()) {churhead = (jsonobject) headiter.next (); // 기본 스타일을 처리 할 경우 (CURHEAD.CONTAINSKEY (this.column_Style)) {colstyle = curhead.get (this.column_style); {HeadCellStyleKeys [ColIndex] = this.columnstyle_prev+ colindex; this.userstyles.put (HeadcellSteyekeys [Colindex], this.createCellstyle ((jsonObject) Colstyle));} else if (this.userstyles.containskey (Colstyle)) {HeadCellStylekeys [colindex] = (string) colstyle;}} // haldent default hant (CURHEAD.CONTAINSKEY (this.column_width)) {ws.setDefaultColumnWidth (pixtoExcelwdith (churehead.getIntValue (this.column_width));} // (cuphead.column key (this.column_type)) {colindexpes = hearhead.getString (this.column_type);} else {headtypes [colindex] = this.celltypestring;} // 다중 테이블 헤더 colname = cuphead.getstring (this.column_name); colameary = colname.split ( "//"); colameary.length.length.length. collevel; if (collevel> maxlevel) {maxlevel = collevel;} for (int i = 0; i <collevel; i ++) {if (headvaluelist.size () <= i) {headvaluelist.add (new arraylist <string> ());} headvaluelist.get (i) .get [i); ws. getrow (sheetrowindex + i); if (row == null) {row = ws.createrow (sheetrowindex+i);} headcell = row.createcell (colindex); headcell.setcellvalue (colenameary [i]); headcell.setcellstyle (this.userstyles.get (this.headstyle_key)); iterator <arraylist <string>> a = headvaluelist.iterator (); jsonarray headmerge = new JsonArray (); String prev = ""; String current = null; int lrowindex = 0; int startcol = 0; int mergecol = 0; arraylist <string> columnInfo = null; ""; columnInfo = a.next (); // 세 번째 열에서만 첫 번째 및 두 번째 열이 병합되어 있는지 알 수 있습니다. columnInfo.add ( ""); iterator <string> b = collectinfo.iterator (); xssfcell lastrowcell = null; while (b.hasnext ()) {current = b.next (); if (lrowindex> 0) {lastowcell = ws.getrow (sheetrowindex + lrowindex- 1); ggetcell (startcol); (prev.equalsignorecase (현재) && lrowindex == 0) {ws.getrow (stewrowindex+lrowindex) .getCell (startCol) .SetCellType (cell.cell_type_blank); mergecol ++;} else if (prev.equalsignorecase (현재) && 0 && 0 && stringUtils.isblank (lastowcell.getStringCellValue ())) {ws.getRow (starkEndex+lrowIndex) .getCell (startCol) .setCellType (cell.cell_Type_Blank); mergecol ++;} else {if (mergecol> 0 && startcol> 0). {headmerge.add (String.format ( "%d,%d,%d,%d,%d", lrowindex, lrowindex, startcol -1, startcol -1); mergecol = 0;}} startcol ++; prev = current;} lrowindex ++; <maxlevel) {// 열 병합이 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+ r) .createCell (i) .setCellStyle (this.userstyles.get (this.headstyle_key));}}} this.SetMergeCells (ws, headmerge, sheetrowindex); return sheetrowindex + maxlevel;}.그림을 추가하면 셀 점이 기본적으로 사용되며 그림은 지정된 셀 영역 내에서 고정됩니다.
private void addimg (xssfsheet ws, jsonobject img, xssfcreationhelper chelper) {String imgbase64 = img.getString (this.sheet_img_data); if (stringUtils.isblank (imgbase64)) retring; string [] imgary = imgbase64.split ( ","); system.out.println (imgary [0]); byte [] imgbyte = base64.decodebase64 (imgary [1]); int imgidx = wb.addpicture (imgbyte, workbook.picture_type_jpeg); ws.createdRawingPatriArch (); xssfclientAnchor 앵커 = chelper.createClientAnchor (); int col = img.getIntValue (this.sheet_img_col); int row = img.getIntValue (this.sheet_img_row); 앵커); 앵커); drawimg.createpicture (앵커, imgidx); 정수 colspan = img.getinteger (this.sheet_img_colspan); if (colspan == null) colspan = 1; integer rowspan = img.getInteger (this.sheet_img_rowspan); if (rowspan == null) rowspan = rowspan == null). 1; pict.resize (Colspan, rowspan);} 5. 요약
이번에는 JSON 객체를 전달하여 리치 스타일 Excel 파일을 생성했으며 POI Operation Office 문서에 더 익숙합니다. Parsing Excel 문서와 비교할 때, 2003 형식과 호환되는 것과 같은 파일 형식을 고려할 필요는 없습니다. 큰 파일 SAX 구문 분석이 고려됩니다. Excel 파일의 JS 프론트 엔드 생성과 비교하여 생성 된 파일의 2 차 처리 가능성이 증가하므로 기능적 입구에서는 이진 스트림 생성 방법이 채택됩니다. 파일이 생성 된 후에는 이메일을 계속 보내고 FTP 및 기타 작업을 업로드 할 수 있습니다.
키 노트
좋아, 위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.