1。背景
Apache Poiは、Office Open XML(OOXML)標準およびMicrosoftのOLE 2 Composite Document Format(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はとして使用されません。 2つの列と2行を表す必要がある場合、最初の列マージヘッダー形式は次のとおりです。
| a | |
| b | c |
フロントエンドは、ポストを通じて要件と提出と背景を満たすJSONファイルとして生成されるデータを構築します。上記の要件に従ってJSON形式を次のように定義します
{"savename": "Excel file name.xlsx"、 "userstyles"を生成する:[{"id": "1"、//複製なし、セルスタイルを設定する必要がある場合、スタイルを直接割り当てることができます。 "#ff0000"、// font color "name": "microsoft elegant black"、// font name "height":20 // size}、 "fmtstr": ""、//セル形式、#、## 0.00 _);ボトム「bordercolor ":" "、//#ff0000" bgcolor "などの境界色の色を設定:" //セルの塗りつぶし}}]、 "sheets":[{"sheetname": ""、//シート名 ":情報 "data":[]、// data information "datamerge":[]、//データマージ情報 "足":[]、//テーブルエンド情報 "footmerge":[]、//テーブルエンドマージ情報 "img":[] //画像をbase64}]}}簡単な説明
ヘッドアレイのJSONオブジェクト形式はです
{"name": "a | b"、//テーブルヘッダー名、マルチテーブルヘッダーの使用| 「タイプ」:「str」を分割するには、//配列タイトルデータフットでは、リスト内のデータは、オブジェクトである場合、1、「A」、またはオブジェクトなどの個別の値にすることができます。
{"value": ""、//セルの特定の値 "Type": ""、//セルタイプ、デフォルトのstr "スタイル":{} //セルスタイルはスタイルオブジェクト、またはusersylesで定義されたID値です。設定されていない場合、ヘッドはデフォルトでこのコラムの対応するスタイルです} Titlemerge、Datamerge、およびFootmergeアレイの値は、「開始行、終了行、開始列、終了列」を意味するコンマ区切り文字列です。インデックスは0から始まります。タイトルに2つの行と3列のデータがある場合、1つの行の対応する値と2つの列のデータと2つの列をマージする必要があります。
IMG配列の値はオブジェクト、形式です
{"col":1、//画像開始列 "行":0、//開始行 "colspan":1、//列の値は1 "rowspan"です。 4。キー実装
07以降のExcelファイルは実際には圧縮パッケージであり、各シートはXMLファイルであり、スタイルはXMLファイルであり、画像は対応する画像ファイルであり、メディアフォルダーに配置されているため、コードのアイデアは
関数ポータルは次のとおりです
@OverridePublic void buildOutputStream()THROWS FILEPRODUCEREXCEPTION {//入力JSONデータシート= this.jsondata.getJSonarray(this.sheets); iterator <object> sheetiter = sheets.iterator(); if(sheets.isempty())) {this.responsedata.seterrcode(1001); this.responsedata.setsuccess(false); this.responsedata.seterrmsg( "データは生成できません");新しいfileproducerexception();} wb = new xssfworkbook(); this.jsondata.getjsonarray(this.userstyles); this.InituserStyles(userStyles); this.initdefaultheadstyle(); XSSFSHEET WS; jsonObjectシート; jsonarray sheetdata; JSonarray Sheettitle; Jsonarray Sheethead; jsonarray sheetfoot; JSonArray Sheetimgs; string sheetname; int sheetindex = 0; while(sheetter.hasnext()){sheet =(jsonobject)sheetter.next(); //シート名sheetname = sheet.getString(this.sheet_name); ws = wb.createsheet(); if(stringutils.isname(sheetname)) sheetName);} int sheetrowindex = 0; sheettitle = sheet.getjsonarray(this.sheet_title); this.setmergecells(ws、sheet.getjsonarray(this.sheet_title_merge)、sheetrowindex); sheethowindex = this.createrandom(ws、sheettitle、sheetrowindex); sheethead = sheet.getjsonarray(this.sheet_head); sheethowindex = 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);} // returen output stream try {bytearrayoutputStream os = new bytearrayoutputStream(); wb.write(os); this.outstreams.add(os);} catch(ioexception e){show new fileproducerexception(e.getMessage()、e.getCause();}}}フォントボーダーの背景アライメントを含むセルスタイルオブジェクトを生成します
private xssfcellstyle createcellstyle(jsonobject style){xssfcellstyle cellstyle = wb.createcellstyle(); // set font jsonobject font = style.getjsonobject(this.style_font); {cellStyle.setFont(Excelfont);} // Border統合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.substring(1)、16)); xfbordercolor); cellstyle.setbordercolor(borderside.top、xfbordercolor); cellStyle.setbordercolor(borderside.left、xfbordercolor); cellstyle.setbordercolor(borderside.right、xfordercolor); style.getString(this.background_color); if(stringutils.isnotblank(bgcolor)){xssfcolor cellbgcolor = new xssfcolor(new color(integer.parseint(bgcolor.substring(1))、 16))); cellStyle.setFillForeGroundColor(cellbgColor); cellStyle.setFillPattern(fillPatterntype.Solid_foreground);} // alignment string halignment = style.getString(this.halignment); if (stringutils.isnotblank(halignment))cellstyle.setalignment(horizontalalignment.valueof(halignment.touppercase())); string valignment = style.getString(this.valignment); if (stringutils.isnotblank(valignment))cellstyle.setvertalAlignment(verticalAlignment.valueof(valignment.touppercase())); //フォーマット文字列fmt = style.getString(this.fmtstring); if(stringutils.isnotblank(fmt))cellstyle.setdataformat(wb.createdataformat()。getformat(fmt)); return cellstyle;}フォントスタイルを作成します
プライベートフォントcreatefont(jsonobject fontcfg){if(fontcfg == null)return null; xssffont font = wb.createfont(); font.setfontname(fontcfg.getString(this.font_name)); boolean fontboole = fontcfg.getboolean(fontboolean(fontboole); null)font.setbold(fontboole.booleanvalue()); fontboole = fontcfg.getboolean(this.font_italic); if(fontboole!= null)font.setitalic(fontboole.booleanvalue()); fontboole = fontcfg.getboolin(fontcfg.fonline(fontben); != null && fontboole.booleanvalue()== true)font.setunderline(fontunderline.single.getBytevalue()); short fontheight = fontcfg.getShort(this.font_height); if(fontheight!= null) fontcfg.getString(this.font_color); if(colorsstr!= null){font.setColor(new XSSFColor(new Color(integer.substring(1)、16)));} return font;}テーブルヘッダーを処理するには、あまりにも多くのテーブルヘッダーが処理され、|セグメンテーション方法が使用されます。頭の長さは列データです。いくつかあります|名前では、ヘッダーにいくつの行があるかがわかります。したがって、ヘッダー処理にはいくつかのステップがあります
private int createheadcolumn(xssfsheet ws、jsonarray sheethead、int sheetrowindex){if(sheethead == null)return sheetrowindex; iterator <object> headiterator = sheethead.iterator(); jsonobject curhead = null; int colindex = 0; objectyle = null; int colsizepes string [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 <arraylist <arraylist <arraylist <arraylist <arraylist <arraylist <arraylist <arraylist <arrayList < arrayList <arrayList <string >>(); while(headiter.hasnext()){curhead =(jsonobject)headiter.next(); //デフォルトスタイルをハンドルif(curhead.column_style)){colstyle = curhead.get(this.column_style); if(coltyle insculting of of of( {headcellstylekeys [colindex] = this.columnstyle_prev+ colindex; this.userstyles.put(headcellstylekeys [colindex]、this.createcellstyle((jsonobject)colstyle));} else if(this.userstyles.containskey(colstyle)){headcellstylekeys [colindex] =(string)colstyle;}}/}/}/}/} (curhead.containskey(this.column_width)){ws.setDefaultColumnWidth(pixtoexcelwdith(curhead.getIntValue(this.column_width)) curhead.getString(this.column_type);} else {headtypes [colindex] = this.celltypestring;} //ハンドルマルチテーブルヘッダーcolname = curhead.getString(this.column_name); 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); ws.getrow(sheetrowindex + i); if(row == null){row = ws.createrow(sheetrowindex+i);} headcell = row.createcell(colindex); headcell.setcellvalue(colnameary [i]); 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> columminfo = null; ""; columninfo = a.next(); // 3番目の列でのみ、最初の列と2番目の列がマージされているかどうかを知ることができます。 columnInfo.add( ""); iterator <string> b = columninfo.iterator(); xssfcell lastrowcell = null; while(b.hasnext()){current = b.next(); if(lrowindex> 0){lastrowcell = wsegrow(sheetrowindex + lrowindex + lrowindex -1)。 (prev.equalsignorecase(current)&& lrowindex == 0){ws.getrow(sheetrowindex+lrowindex).getcell(startcol).setcelltype(cell.cell_type_blank); mergecol ++;} els stringutils.isblank(lastrowcell.getStringCellValue())){ws.getRow(sheetrowindex+lrowindex).getCell(startcol).setCellType(cell.cell_type_blank); mergecol ++;}それは{if(mergecol> 0 &> 0 &> 0) {headmerge.add(string.format( "%d、%d、%d、%d"、lrowindex、lrowindex、startcol -mergecol -1、startcol -1) (headcollevel [i] <maxlevel){//列マージはheadmerge.add( "%d、%d、%d、%d"、headcollevel [i] -1、maxlevel -1、i、i)); 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))return; imgbase64.split( "、"); system.out.println(imgary [0]); byte [] imgbyte = base64.decodeBase64(imgary [1]); int imgidx = wb.addpicture(imgbyte、workbook.picture_type_jpeg); xsfdrawing 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); pict = drawimg.createpicture(anchor、imgidx); integer colspan = img.getinteger(this.sheet_img_colspan); if(colspan == null)colspan = 1; 1; pict.resize(colspan、rowspan);} 5。概要
今回は、JSONオブジェクトを渡すことでリッチなスタイルのExcelファイルを生成しました。POIOperation Office Documentsに精通しています。 Excelドキュメントの解析と比較して、2003年の形式と互換性があり、大規模なファイルSAXの解析など、生成時にファイル形式を考慮する必要はありません。 ExcelファイルのJSフロントエンド生成と比較して、生成されたファイルの二次処理の可能性が増加するため、機能的な入り口では、バイナリストリームを生成する方法が採用されます。ファイルが生成された後、電子メールの送信、FTPおよびその他の操作のアップロードを引き続き送信できます。
キーノート
さて、上記はこの記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。