Browse Source

提交demo代码

10.0
hugh 3 years ago
parent
commit
acf4ab0c75
  1. 4
      README.md
  2. 124
      build.gradle
  3. 94
      comment_excel.cpt
  4. 13
      encrypt.xml
  5. BIN
      lib/common-kit-10.0-20210309.jar
  6. BIN
      lib/finekit-10.0-20210309.jar
  7. 16
      plugin.xml
  8. 134
      src/main/java/com/tptj/demo/hg/comment/excel/processor/Demo.java
  9. 88
      src/main/java/com/tptj/demo/hg/comment/excel/processor/ExcelDictionary.java
  10. 53
      src/main/java/com/tptj/demo/hg/comment/excel/processor/ExcelDictionaryBuilder.java

4
README.md

@ -1,3 +1,5 @@
# demo-comment-excel-processor
导出excel单sheet处理(批注处理)接口demo
导出excel单sheet处理(批注处理)接口demo\
demo生效后,填报模式访问附件模板导出excel。导出的excel文件对应的单元格支持下拉框选择\
注:只支持excel 2007版本(03版本接口不支持)

124
build.gradle

@ -0,0 +1,124 @@
apply plugin: 'java'
[compileJava,compileTestJava]*.options*.encoding = 'UTF-8'
ext {
/**
* jar的路径
* 1.jar需要打包到zip中,lib根目录下
* 2.jar仅仅是编译时需要lib下子目录下即可
*/
libPath = "$projectDir/../webroot/WEB-INF/lib"
/**
* class进行加密保护
*/
guard = false
def pluginInfo = getPluginInfo()
pluginPre = "fine-plugin"
pluginName = pluginInfo.id
pluginVersion = pluginInfo.version
outputPath = "$projectDir/../webroot/WEB-INF/plugins/plugin-" + pluginName + "-1.0/classes"
}
group = 'com.fr.plugin'
version = '10.0'
sourceCompatibility = '8'
sourceSets {
main {
java.outputDir = file(outputPath)
output.resourcesDir = file(outputPath)
}
}
ant.importBuild("encrypt.xml")
//ant变量
ant.projectDir = projectDir
ant.references["compile.classpath"] = ant.path {
fileset(dir: libPath, includes: '**/*.jar')
fileset(dir: ".",includes:"**/*.jar" )
}
classes.dependsOn('clean')
task copyFiles(type: Copy,dependsOn: 'classes'){
from outputPath
into "$projectDir/classes"
}
task preJar(type:Copy,dependsOn: guard ? 'compile_encrypt_javas' : 'compile_plain_javas'){
from "$projectDir/classes"
into "$projectDir/transform-classes"
include "**/*.*"
}
jar.dependsOn("preJar")
task makeJar(type: Jar,dependsOn: preJar){
from fileTree(dir: "$projectDir/transform-classes")
baseName pluginPre
appendix pluginName
version pluginVersion
destinationDir = file("$buildDir/libs")
doLast(){
delete file("$projectDir/classes")
delete file("$projectDir/transform-classes")
}
}
task copyFile(type: Copy,dependsOn: ["makeJar"]){
from "$buildDir/libs"
from("$projectDir/lib") {
include "*.jar"
}
from "$projectDir/plugin.xml"
into file("$buildDir/temp/plugin")
}
task zip(type:Zip,dependsOn:["copyFile"]){
from "$buildDir/temp/plugin"
destinationDir file("$buildDir/install")
baseName pluginPre
appendix pluginName
version pluginVersion
}
//build时包含哪些文件,
processResources {
// exclude everything
// *.css没效果
// exclude '**/*.css'
// except this file
// include 'xx.xml'
}
/*读取plugin.xml中的version*/
def getPluginInfo(){
def xmlFile = file("plugin.xml")
if (!xmlFile.exists()) {
return ["id":"none", "version":"1.0.0"]
}
def plugin = new XmlParser().parse(xmlFile)
def version = plugin.version[0].text()
def id = plugin.id[0].text()
return ["id":id,"version":version]
}
repositories {
mavenLocal()
maven {
url = uri('http://mvn.finedevelop.com/repository/maven-public/')
}
}
dependencies {
//使jar
implementation fileTree(dir: 'lib', include: ['**/*.jar'])
implementation fileTree(dir: libPath, include: ['**/*.jar'])
}

94
comment_excel.cpt

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<WorkBook xmlVersion="20170720" releaseVersion="10.0.0">
<TableDataMap>
<TableData name="Embedded1" class="com.fr.data.impl.EmbeddedTableData">
<Parameters/>
<DSName>
<![CDATA[]]></DSName>
<ColumnNames>
<![CDATA[K,,.,,V]]></ColumnNames>
<ColumnTypes>
<![CDATA[java.lang.String,java.lang.String]]></ColumnTypes>
<RowData ColumnTypes="java.lang.String,java.lang.String">
<![CDATA[F6#1=EoJq8Eoo4@EoAhU!!~
]]></RowData>
</TableData>
</TableDataMap>
<Report class="com.fr.report.worksheet.WorkSheet" name="sheet1">
<ReportPageAttr>
<HR/>
<FR/>
<HC/>
<FC/>
</ReportPageAttr>
<ColumnPrivilegeControl/>
<RowPrivilegeControl/>
<RowHeight defaultValue="723900">
<![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight>
<ColumnWidth defaultValue="2743200">
<![CDATA[2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth>
<CellElementList>
<C c="0" r="0">
<PrivilegeControl/>
<Expand/>
</C>
<C c="0" r="1">
<O>
<![CDATA[选择]]></O>
<PrivilegeControl/>
<Expand/>
</C>
<C c="1" r="1">
<O t="I">
<![CDATA[1]]></O>
<PrivilegeControl/>
<Widget class="com.fr.form.ui.ComboBox">
<WidgetAttr description="">
<MobileBookMark useBookMark="false" bookMarkName="" frozen="false"/>
<PrivilegeControl/>
</WidgetAttr>
<Dictionary class="com.fr.data.impl.TableDataDictionary">
<FormulaDictAttr kiName="V" viName="K"/>
<TableDataDictAttr>
<TableData class="com.fr.data.impl.NameTableData">
<Name>
<![CDATA[Embedded1]]></Name>
</TableData>
</TableDataDictAttr>
</Dictionary>
<widgetValue/>
</Widget>
<Present class="com.fr.base.present.DictPresent">
<Dictionary class="com.fr.data.impl.TableDataDictionary">
<FormulaDictAttr kiName="V" viName="K"/>
<TableDataDictAttr>
<TableData class="com.fr.data.impl.NameTableData">
<Name>
<![CDATA[Embedded1]]></Name>
</TableData>
</TableDataDictAttr>
</Dictionary>
</Present>
<Expand/>
</C>
</CellElementList>
<ReportAttrSet>
<ReportSettings headerHeight="0" footerHeight="0">
<PaperSetting/>
<Background name="ColorBackground" color="-1"/>
</ReportSettings>
</ReportAttrSet>
<PrivilegeControl/>
</Report>
<ReportParameterAttr>
<Attributes showWindow="true" delayPlaying="true" windowPosition="1" align="0" useParamsTemplate="true" currentIndex="0"/>
<PWTitle>
<![CDATA[参数]]></PWTitle>
</ReportParameterAttr>
<StyleList/>
<DesignerVersion DesignerVersion="KAA"/>
<PreviewType PreviewType="0"/>
<TemplateIdAttMark class="com.fr.base.iofile.attr.TemplateIdAttrMark">
<TemplateIdAttMark TemplateId="b420b7bc-7c50-496f-abd5-f18a29bd445e"/>
</TemplateIdAttMark>
</WorkBook>

13
encrypt.xml

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<target name="compile_encrypt_javas" depends="copyFiles">
<echo message="加密文件"/>
<echo message="${projectDir}"/>
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask">
<classpath refid="compile.classpath"/>
</taskdef>
<pretreatment baseDir="${projectDir}"/>
</target>
<target name="compile_plain_javas" depends="copyFiles">
</target>
</project>

BIN
lib/common-kit-10.0-20210309.jar

Binary file not shown.

BIN
lib/finekit-10.0-20210309.jar

Binary file not shown.

16
plugin.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin>
<id>com.tptj.demo.hg.comment.excel.processor.v10</id>
<name><![CDATA[ comment excel processor ]]></name>
<active>yes</active>
<version>1.0</version>
<env-version>10.0</env-version>
<vendor>tptj</vendor>
<jartime>2019-07-18</jartime>
<description><![CDATA[ ]]></description>
<change-notes><![CDATA[]]></change-notes>
<main-package>com.tptj.demo.hg.comment.excel.processor</main-package>
<function-recorder class="com.tptj.demo.hg.comment.excel.processor.Demo"/>
<extra-report>
<CommentExcelProcessor class="com.tptj.demo.hg.comment.excel.processor.Demo"/>
</extra-report>
</plugin>

134
src/main/java/com/tptj/demo/hg/comment/excel/processor/Demo.java

@ -0,0 +1,134 @@
package com.tptj.demo.hg.comment.excel.processor;
import com.fanruan.api.log.LogKit;
import com.fr.form.ui.ComboBox;
import com.fr.form.ui.DictContainedCustomWriteAbleEditor;
import com.fr.form.ui.Widget;
import com.fr.intelli.record.Focus;
import com.fr.invoke.Reflect;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.report.cell.AbstractWidgetCellElement;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.ResultCellElement;
import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.PageExportCellElement;
import com.fr.report.core.PackedReport;
import com.fr.report.core.lkd.KW;
import com.fr.report.elementcase.ElementCase;
import com.fr.report.fun.impl.AbstractCommentExcelProcessor;
import com.fr.report.report.ResultReport;
import com.fr.report.worksheet.CalculatableResWorkSheet;
import com.fr.stable.ColumnRow;
import com.fr.third.v2.org.apache.poi.ss.usermodel.*;
import com.fr.third.v2.org.apache.poi.xssf.streaming.SXSSFCell;
import com.fr.third.v2.org.apache.poi.xssf.streaming.SXSSFRow;
import com.fr.third.v2.org.apache.poi.xssf.streaming.SXSSFSheet;
import com.fr.third.v2.org.apache.poi.xssf.streaming.SXSSFWorkbook;
import com.fr.third.v2.org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import com.fr.write.core.cal.BCE_WRITE;
import com.fr.write.main.WriteRWorkBook;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-13
**/
@EnableMetrics
public class Demo extends AbstractCommentExcelProcessor {
@Override
@Focus(id="com.tptj.demo.hg.comment.excel.processor.v10",text = "comment excel processor")
public void addCellComment( Sheet sheet, ElementCase report, Drawing drawing ) {
//先获取结果报表,只有填报允许导出下拉框数据字典选项
Workbook workbook = sheet.getWorkbook();
ResultReport result = ((PackedReport) report).getPackee();
ResultWorkBook resultWorkBook = result.getResultWorkBook();
if( !(resultWorkBook instanceof WriteRWorkBook) ){
return;
}
//遍历单元格,对所有下拉框数据字典进行相同合并操作
Iterator iterator = report.cellIterator();
ExcelDictionaryBuilder builder = new ExcelDictionaryBuilder();
while(iterator.hasNext()){
Object cell = iterator.next();
CellElement oldCell = ((PageExportCellElement) cell).getOldCell();
Widget wgt = ((AbstractWidgetCellElement)oldCell).getWidget();
if( null == wgt ){
//适应混淆的代码
TemplateCellElement tcell = Reflect.on(oldCell).call("getBeFrom").call("get_ce_from").get();
wgt = tcell.getWidget();
}
if( null == wgt ){
continue;
}
if( !(wgt instanceof ComboBox) ){
continue;
}
builder.add(new ExcelDictionary((CalculatableResWorkSheet)result,
(DictContainedCustomWriteAbleEditor)wgt),(ResultCellElement)cell);
}
//在excel中生成具体的选项数据
try {
List<ExcelDictionary> build = builder.build();
createBox((SXSSFWorkbook)workbook,sheet,build);
} catch (Exception e) {
LogKit.error(e.getMessage(),e);
}
}
@Override
public void convertCommentToTooltip( CellElement cellElement, Cell cell ) {
}
/**
* 创建一个隐藏的sheet来保存数据字典的数据
* @param wb
* @param sheet
* @param list
*/
private void createBox(SXSSFWorkbook wb, Sheet sheet, List<ExcelDictionary> list) {
int sheetCount = wb.getNumberOfSheets();
String sheetName = "hidden1949"+sheetCount;
SXSSFSheet nsheet = wb.createSheet(sheetName);
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(null);
int maxRow = 0;
for( ExcelDictionary item : list ){
if(item.getData().length > maxRow ){
maxRow = item.getData().length;
}
}
//把所有的选项填充到sheet中
for( int ridx =0;ridx<maxRow; ridx++ ){
SXSSFRow row = nsheet.createRow(ridx);
for( int col=0;col <list.size();col++ ){
ExcelDictionary item = list.get(col);
String[] data = item.getData();
if( data.length > ridx ){
SXSSFCell cell = row.createCell(col);
cell.setCellValue(data[ridx]);
}
}
}
for( int col=0;col <list.size();col++ ){
ExcelDictionary item = list.get(col);
String[] data = item.getData();
if(0 == data.length){
continue;
}
Name namedCell = wb.createName();
String formulaId = "s"+ UUID.randomUUID().toString().replace("-", "");
namedCell.setNameName(formulaId);
String cTag = ColumnRow.valueOf(col,0).toString().replaceAll("1","");
namedCell.setRefersToFormula(sheetName+"!$"+cTag+"$1:$"+cTag+"$" + data.length);
DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(formulaId);
DataValidation dataValidation = dvHelper.createValidation(dvConstraint,item.getCells());
sheet.addValidationData(dataValidation);
}
wb.setSheetHidden(sheetCount, true);
}
}

88
src/main/java/com/tptj/demo/hg/comment/excel/processor/ExcelDictionary.java

@ -0,0 +1,88 @@
package com.tptj.demo.hg.comment.excel.processor;
import com.fr.form.data.WidgetDataOutput;
import com.fr.form.data.WidgetOutletFactory;
import com.fr.form.ui.DictContainedCustomWriteAbleEditor;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONArray;
import com.fr.report.cell.ResultCellElement;
import com.fr.report.worksheet.CalculatableResWorkSheet;
import com.fr.stable.script.CalculatorProvider;
import com.fr.third.springframework.web.context.request.RequestContextHolder;
import com.fr.third.springframework.web.context.request.ServletRequestAttributes;
import com.fr.third.v2.org.apache.poi.ss.util.CellRangeAddressList;
import com.fr.web.core.SessionPoolManager;
import com.fr.web.core.WidgetSessionIDInfor;
import com.fr.web.utils.WebUtils;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-13
**/
public class ExcelDictionary {
private CalculatableResWorkSheet sheet;
private DictContainedCustomWriteAbleEditor wgt;
private CellRangeAddressList cells;
private String[] data = new String[0];
public ExcelDictionary( CalculatableResWorkSheet sheet, DictContainedCustomWriteAbleEditor wgt ){
this.sheet = sheet;
this.wgt = wgt;
cells = new CellRangeAddressList();
}
/**
* 判断目标数据字典与缓存数据字典是否是同一个是的话就会进行区域的合并
* @param dic
* @return
*/
public boolean isSameDic( ExcelDictionary dic ){
return ComparatorUtils.equals( dic.getWgt().getDictionary(), wgt.getDictionary() );
}
public DictContainedCustomWriteAbleEditor getWgt() {
return wgt;
}
/**
* 同一个数据字典可以对多个单元格生效通过该方法进行区域的指定
* @param cell
*/
public void addCells( ResultCellElement cell ){
int row = cell.getRow();
int col = cell.getColumn();
int rspan = cell.getRowSpan();
int cspan = cell.getColumnSpan();
cells.addCellRangeAddress( row, col, row + rspan -1, col + cspan -1 );
}
/**
* 生成字典数据
* @throws Exception
*/
public void build()throws Exception{
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
WidgetDataOutput widgetDataOutlet = WidgetOutletFactory.createWidgetDataOutlet(attrs.getRequest(), wgt);
String sessionId = WebUtils.getHTTPRequestParameter(attrs.getRequest(),"sessionID");
WidgetSessionIDInfor info = SessionPoolManager.getSessionIDInfor(sessionId, WidgetSessionIDInfor.class);
CalculatorProvider calculator = sheet.getCalculator();
JSONArray jsonData = widgetDataOutlet.createJSONData(info, calculator, attrs.getRequest(), wgt);
data = new String[jsonData.size()];
for( int i=0;i<data.length;i++ ){
data[i] = jsonData.optJSONObject(i).optString("text");
}
}
public String[] getData() {
return data;
}
public CellRangeAddressList getCells() {
return cells;
}
}

53
src/main/java/com/tptj/demo/hg/comment/excel/processor/ExcelDictionaryBuilder.java

@ -0,0 +1,53 @@
package com.tptj.demo.hg.comment.excel.processor;
import com.fr.report.cell.ResultCellElement;
import java.util.ArrayList;
import java.util.List;
/**
* @author 秃破天际
* @version 10.0
* Created by 秃破天际 on 2021-04-13
**/
public class ExcelDictionaryBuilder {
/**
* 统一记录一个sheet包含的所有数据字典把相同的进行归类合并
*/
private List<ExcelDictionary> list = new ArrayList<ExcelDictionary>();
/**
* 进行归类合并操作
* @param dic
* @param cell
*/
public void add(ExcelDictionary dic, ResultCellElement cell ){
ExcelDictionary old = getSameDictionary(dic);
if( null == old ){
list.add(dic);
old = dic;
}
old.addCells(cell);
}
private ExcelDictionary getSameDictionary( ExcelDictionary dic ){
for( ExcelDictionary item : list ){
if( item.isSameDic(dic) ){
return item;
}
}
return null;
}
/**
* 生成所有数据字典的数据
* @return
* @throws Exception
*/
public List<ExcelDictionary> build()throws Exception{
for( ExcelDictionary item : list ){
item.build();
}
return list;
}
}
Loading…
Cancel
Save