目录

一、ktr文件生成

二、分析ktr文件

解析类

文件路径

文件字段

图形化信息

输出节点

三、交换代码

初始化环境

输入节点

输入字段列设置

输出节点

输出节点列设置

设置Trans

将步骤添加到Trans

步骤关联

交换执行

四、问题点

问题、no class found 没有jxl包和poi包

问题、 没有设置includeSubFolders属性

问题、没有设置fileMask和excludeFileMask

问题、没有设置fileRequired

问题、没有设置startRow和startColumn

问题、少包

运行成功

完整交换代码

ktr内容


一、ktr文件生成

定义一个简单的Excel交换,如下图,保存为ktr文件,ktr的内容放在最后了。

二、分析ktr文件

大概浏览一遍ktr文件,有info,notepads,order,step,step_error_handling等节点,

看节点中内容,大概能知道order定义节点顺序,从输入到输出,

解析类

通过分析这个step,能确定我们要找什么Meta对象,需要设置什么参数。

通过红线处的type去kettle的源码中搜索,能在pentaho-kettle-->engine工程中找到一个kettle-steps.xml的文件,通过type确定如下内容,能确定需要使用的是ExcelInputMeta。

<step id="ExcelInput"> <description>i18n:org.pentaho.di.trans.step:BaseStep.TypeLongDesc.ExcelInput</description>  <classname>org.pentaho.di.trans.steps.excelinput.ExcelInputMeta</classname>  <category>i18n:org.pentaho.di.trans.step:BaseStep.Category.Input</category>  <tooltip>i18n:org.pentaho.di.trans.step:BaseStep.TypeTooltipDesc.ExcelInput</tooltip>  <iconfile>ui/images/XLI.svg</iconfile>  <documentation_url>Products/Microsoft_Excel_Input</documentation_url>  <cases_url/>  <forum_url/>
</step>

同理可以找到ExcelOutputMeta这个类。

那么基本就能确定这两个类就是图形化界面的两个节点。

文件路径

在界面进行了两步操作,第一步选择文件,第二步获取文件列,

此处是定义了POI解析,同时设置了文件路径,对应到ktr文件中就是如下内容,

<file><name>F:\kette_test\input\person.xlsx</name><filemask/><exclude_filemask/><file_required>N</file_required><include_subfolders>N</include_subfolders></file>
<spreadsheet_type>POI</spreadsheet_type>

通过上面ktr中xml的节点名称,可以在ExcelInputMeta中找到对应的属性,如下所示,后续就可以通过这些对象属性设值。

 /*** The filenames to load or directory in case a filemask was set.*/@Injection( name = "FILENAME", group = "FILENAME_LINES" )private String[] fileName;/*** The regular expression to use (null means: no mask)*/@Injection( name = "FILEMASK", group = "FILENAME_LINES" )private String[] fileMask;/*** Wildcard or filemask to exclude (regular expression)*/@Injection( name = "EXCLUDE_FILEMASK", group = "FILENAME_LINES" )private String[] excludeFileMask;@Injection( name = "FILE_REQUIRED", group = "FILENAME_LINES" )private String[] fileRequired;@Injection( name = "SPREADSHEET_TYPE" )private SpreadSheetType spreadSheetType;/*** Array of boolean values as string, indicating if we need to fetch sub folders.*/@Injection( name = "INCLUDE_SUBFOLDERS", group = "FILENAME_LINES" )private String[] includeSubFolders;

其中关于includeSubFolders是一个数组,那么就是同fileName这个数组对应的,此字段的含义是是否包含子目录。

includeSubFolders是设置什么值,是Y或者N?从源码中看到这个字段的判断,能看到是设置Y或者N。

在代码运行时,报错jxl的解析类找不到,所以能确定ExcelOutputMeta使用的是jxl写excel,此内容后面有详细报错。

文件字段

无论是输入,还是输出,都定义了列名,而这个列名对应到ktr文件中就是fields节点,如下所示,

<fields><field><name>id</name><type>String</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field><field><name>name</name><type>String</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field><field><name>age</name><type>Integer</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field></fields>

而上述Fields也可以在ExcelInputMeta中找到,这是一个数组ExcelInputField[],

/*** The fields to read in the range. Note: the number of columns in the range has to match field.length*/@InjectionDeepprivate ExcelInputField[] field;

查看ExcelInputField对象,里面的属性是和ktr的xml相似,同时还有构造方法,里面关于type和trimtype是有常量设置,可以用作参考。

 public ExcelInputField( String fieldname, int position, int length ) {this.name = fieldname;this.length = length;this.type = ValueMetaInterface.TYPE_STRING;this.format = "";this.trimtype = ExcelInputMeta.TYPE_TRIM_NONE;this.groupSymbol = "";this.decimalSymbol = "";this.currencySymbol = "";this.precision = -1;this.repeat = false;}

图形化信息

<GUI><xloc>416</xloc><yloc>176</yloc><draw>Y</draw></GUI>

如上GUI节点就能看到在图形化界面展示的信息。

输出节点

输出(ExcelOutputMeta)大部分是和ExcelInputMeta相似,其中有一些需要特殊设置,比如是否需要Excel的头,尾,是否追加文件等。

<header>Y</header><footer>N</footer><encoding/><append>N</append>

从ExcelOutputMeta中也能看到对应的属性,如下所示,

/** Add a header at the top of the file? */@Injection( name = "HEADER_ENABLED", group = "CONTENT" )private boolean headerEnabled;/** Add a footer at the bottom of the file? */@Injection( name = "FOOTER_ENABLED", group = "CONTENT" )private boolean footerEnabled;/** Flag : append workbook? */@Injection( name = "APPEND", group = "CONTENT" )private boolean append;

至此关于Ktr文件的分析和对应代码就找到了,那么就可以尝试写Excel交换代码。

三、交换代码

初始化环境

@Beforepublic void before() {try {//初始化环境EnvUtil.environmentInit();KettleEnvironment.init();} catch (KettleException e) {log.error("", e);}}

输入节点

/*1.excel输入*/ExcelInputMeta inputMeta = new ExcelInputMeta();//文件路径String filePath = "F:\\kette_test\\input\\person.xlsx";String[] fileName = new String[]{filePath};inputMeta.setFileName(fileName);String[] fileMasks = new String[1];inputMeta.setFileMask(fileMasks);String[] fileExcludeMasks = new String[1];inputMeta.setExcludeFileMask(fileExcludeMasks);String[] filerequireds = new String[]{"N"};inputMeta.setFileRequired(filerequireds);String[] subFolders = new String[]{"N"};inputMeta.setIncludeSubFolders(subFolders);inputMeta.setSpreadSheetType(SpreadSheetType.POI);//第二行开始int[] startRow = new int[]{1};inputMeta.setStartRow(startRow);//第一列开始int[] startColumn = new int[]{0};inputMeta.setStartColumn(startColumn);

输入字段列设置

//字段列ExcelInputField[] excelInputFields = new ExcelInputField[3];excelInputFields[0] = new ExcelInputField();excelInputFields[0].setName("id");excelInputFields[0].setType(ValueMetaInterface.TYPE_STRING);excelInputFields[0].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[0].setRepeated(false);excelInputFields[1] = new ExcelInputField();excelInputFields[1].setName("name");excelInputFields[1].setType(ValueMetaInterface.TYPE_STRING);excelInputFields[1].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[1].setRepeated(false);excelInputFields[2] = new ExcelInputField();excelInputFields[2].setName("age");excelInputFields[2].setType(ValueMetaInterface.TYPE_INTEGER);excelInputFields[2].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[2].setRepeated(false);inputMeta.setField(excelInputFields);

输出节点

/*2. excel输出*/ExcelOutputMeta outputMeta = new ExcelOutputMeta();outputMeta.setAppend(false);outputMeta.setHeaderEnabled(true);outputMeta.setFooterEnabled(false);outputMeta.setFileName("F:\\kette_test\\output\\excel输出.xls");outputMeta.setDoNotOpenNewFileInit(false);outputMeta.setCreateParentFolder(false);

输出节点列设置

ExcelField[] excelFields = new ExcelField[3];excelFields[0] = new ExcelField();excelFields[0].setName("id");excelFields[0].setType(ValueMetaInterface.TYPE_STRING);excelFields[1] = new ExcelField();excelFields[1].setName("name");excelFields[1].setType(ValueMetaInterface.TYPE_STRING);excelFields[2] = new ExcelField();excelFields[2].setName("age");excelFields[2].setType(ValueMetaInterface.TYPE_INTEGER);excelFields[2].setFormat("0");outputMeta.setOutputFields(excelFields);

设置Trans

TransMeta transMeta = new TransMeta();
transMeta.setName("excel交换");PluginRegistry registry = PluginRegistry.getInstance();

将步骤添加到Trans

/*3. 添加步骤*/String inputPluginId = registry.getPluginId(StepPluginType.class, inputMeta);StepMeta inputStep = new StepMeta(inputPluginId, "excel-input", (StepMetaInterface) inputMeta);//给步骤添加在spoon工具中的显示位置inputStep.setDraw(true);inputStep.setLocation(200, 200);//将步骤添加进去transMeta.addStep(inputStep);String outPluginId = registry.getPluginId(StepPluginType.class, outputMeta);StepMeta outputStep = new StepMeta(outPluginId, "excel-output", (StepMetaInterface) outputMeta);//给步骤添加在spoon工具中的显示位置outputStep.setDraw(true);outputStep.setLocation(300, 200);transMeta.addStep(outputStep);

步骤关联

/*4. 关联步骤*/transMeta.addTransHop(new TransHopMeta(inputStep, outputStep));

交换执行

/*5.执行*/Trans trans = new Trans(transMeta);//执行转换trans.execute(null);//等待完成trans.waitUntilFinished();if (trans.getErrors() > 0) {System.out.println("交换出错.");return;}

四、问题点

在写出上述代码前,也是运行了碰到很多坑,现在将问题一一罗列出来。

问题、no class found 没有jxl包和poi包

解决方式:

将pdi-ce-8.2.0.0-342\data-integration\lib 中的包拷贝过来并加入到idea中,

问题、 没有设置includeSubFolders属性

如上,告诉你空指针,然后报错是ExcelInputMeta对象的includeSubFolderBoolean方法,跟踪源码发现如下判断,

解决方式:

String[] subFolders = new String[]{"N"};
inputMeta.setIncludeSubFolders(subFolders);

问题、没有设置fileMask和excludeFileMask

继续看源码,跟踪,fileName,fileMask,excludeFileMask是要设值的。

解决方式:

//文件路径
String filePath = "F:\\kette_test\\input\\person.xlsx";
String[] fileName = new String[]{filePath};
inputMeta.setFileName(fileName);String[] fileMasks = new String[1];
inputMeta.setFileMask(fileMasks);String[] fileExcludeMasks = new String[1];
inputMeta.setExcludeFileMask(fileExcludeMasks);

问题、没有设置fileRequired

解决方式:

String[] filerequireds = new String[]{"N"};
inputMeta.setFileRequired(filerequireds);

问题、没有设置startRow和startColumn

这两个属性在ktr文件中是没有的,但是运行报错,通过跟踪源码发现,需要设置这两个属性,否则就是空指针异常了。

解决方式:

默认从0开始读取,这个数组长度和fileName是相匹配的。

//第二行开始int[] startRow = new int[]{1};inputMeta.setStartRow(startRow);//第一列开始int[] startColumn = new int[]{0};inputMeta.setStartColumn(startColumn);

问题、少包

解决方式:

pom.xml中加入相应包,

<dependency><groupId>org.apache.xmlbeans</groupId><artifactId>xmlbeans</artifactId><version>2.6.0</version>
</dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version>
</dependency>

运行成功

一个简单看ktr写代码就完了,好不容易。

完整交换代码

@Beforepublic void before() {try {//初始化环境EnvUtil.environmentInit();KettleEnvironment.init();} catch (KettleException e) {log.error("", e);}}/*** excel之间交换*/@Testpublic void exchangeExcel2Excel() throws KettleException {TransMeta transMeta = new TransMeta();transMeta.setName("excel交换");PluginRegistry registry = PluginRegistry.getInstance();/*1.excel输入*/ExcelInputMeta inputMeta = new ExcelInputMeta();//文件路径String filePath = "F:\\kette_test\\input\\person.xlsx";String[] fileName = new String[]{filePath};inputMeta.setFileName(fileName);String[] fileMasks = new String[1];inputMeta.setFileMask(fileMasks);String[] fileExcludeMasks = new String[1];inputMeta.setExcludeFileMask(fileExcludeMasks);String[] filerequireds = new String[]{"N"};inputMeta.setFileRequired(filerequireds);String[] subFolders = new String[]{"N"};inputMeta.setIncludeSubFolders(subFolders);inputMeta.setSpreadSheetType(SpreadSheetType.POI);//第二行开始int[] startRow = new int[]{1};inputMeta.setStartRow(startRow);//第一列开始int[] startColumn = new int[]{0};inputMeta.setStartColumn(startColumn);//字段列ExcelInputField[] excelInputFields = new ExcelInputField[3];excelInputFields[0] = new ExcelInputField();excelInputFields[0].setName("id");excelInputFields[0].setType(ValueMetaInterface.TYPE_STRING);excelInputFields[0].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[0].setRepeated(false);excelInputFields[1] = new ExcelInputField();excelInputFields[1].setName("name");excelInputFields[1].setType(ValueMetaInterface.TYPE_STRING);excelInputFields[1].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[1].setRepeated(false);excelInputFields[2] = new ExcelInputField();excelInputFields[2].setName("age");excelInputFields[2].setType(ValueMetaInterface.TYPE_INTEGER);excelInputFields[2].setTrimType(ExcelInputMeta.TYPE_TRIM_NONE);excelInputFields[2].setRepeated(false);inputMeta.setField(excelInputFields);/*2. excel输出*/ExcelOutputMeta outputMeta = new ExcelOutputMeta();outputMeta.setAppend(false);outputMeta.setHeaderEnabled(true);outputMeta.setFooterEnabled(false);outputMeta.setFileName("F:\\kette_test\\output\\excel输出.xls");outputMeta.setDoNotOpenNewFileInit(false);outputMeta.setCreateParentFolder(false);ExcelField[] excelFields = new ExcelField[3];excelFields[0] = new ExcelField();excelFields[0].setName("id");excelFields[0].setType(ValueMetaInterface.TYPE_STRING);excelFields[1] = new ExcelField();excelFields[1].setName("name");excelFields[1].setType(ValueMetaInterface.TYPE_STRING);excelFields[2] = new ExcelField();excelFields[2].setName("age");excelFields[2].setType(ValueMetaInterface.TYPE_INTEGER);excelFields[2].setFormat("0");outputMeta.setOutputFields(excelFields);/*3. 添加步骤*/String inputPluginId = registry.getPluginId(StepPluginType.class, inputMeta);StepMeta inputStep = new StepMeta(inputPluginId, "excel-input", (StepMetaInterface) inputMeta);//给步骤添加在spoon工具中的显示位置inputStep.setDraw(true);inputStep.setLocation(200, 200);//将步骤添加进去transMeta.addStep(inputStep);String outPluginId = registry.getPluginId(StepPluginType.class, outputMeta);StepMeta outputStep = new StepMeta(outPluginId, "excel-output", (StepMetaInterface) outputMeta);//给步骤添加在spoon工具中的显示位置outputStep.setDraw(true);outputStep.setLocation(300, 200);transMeta.addStep(outputStep);/*4. 关联步骤*/transMeta.addTransHop(new TransHopMeta(inputStep, outputStep));/*5.执行*/Trans trans = new Trans(transMeta);//执行转换trans.execute(null);//等待完成trans.waitUntilFinished();if (trans.getErrors() > 0) {System.out.println("交换出错.");return;}}

ktr内容

<?xml version="1.0" encoding="UTF-8"?>
<transformation><info><name>excel交换</name><description/><extended_description/><trans_version/><trans_type>Normal</trans_type><directory>/</directory><parameters></parameters><log><trans-log-table><connection/><schema/><table/><size_limit_lines/><interval/><timeout_days/><field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STATUS</id><enabled>Y</enabled><name>STATUS</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name><subject/></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name><subject/></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name><subject/></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name><subject/></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name><subject/></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name><subject/></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>STARTDATE</id><enabled>Y</enabled><name>STARTDATE</name></field><field><id>ENDDATE</id><enabled>Y</enabled><name>ENDDATE</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>DEPDATE</id><enabled>Y</enabled><name>DEPDATE</name></field><field><id>REPLAYDATE</id><enabled>Y</enabled><name>REPLAYDATE</name></field><field><id>LOG_FIELD</id><enabled>Y</enabled><name>LOG_FIELD</name></field><field><id>EXECUTING_SERVER</id><enabled>N</enabled><name>EXECUTING_SERVER</name></field><field><id>EXECUTING_USER</id><enabled>N</enabled><name>EXECUTING_USER</name></field><field><id>CLIENT</id><enabled>N</enabled><name>CLIENT</name></field></trans-log-table><perf-log-table><connection/><schema/><table/><interval/><timeout_days/><field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>SEQ_NR</id><enabled>Y</enabled><name>SEQ_NR</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>INPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>INPUT_BUFFER_ROWS</name></field><field><id>OUTPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>OUTPUT_BUFFER_ROWS</name></field></perf-log-table><channel-log-table><connection/><schema/><table/><timeout_days/><field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>LOGGING_OBJECT_TYPE</id><enabled>Y</enabled><name>LOGGING_OBJECT_TYPE</name></field><field><id>OBJECT_NAME</id><enabled>Y</enabled><name>OBJECT_NAME</name></field><field><id>OBJECT_COPY</id><enabled>Y</enabled><name>OBJECT_COPY</name></field><field><id>REPOSITORY_DIRECTORY</id><enabled>Y</enabled><name>REPOSITORY_DIRECTORY</name></field><field><id>FILENAME</id><enabled>Y</enabled><name>FILENAME</name></field><field><id>OBJECT_ID</id><enabled>Y</enabled><name>OBJECT_ID</name></field><field><id>OBJECT_REVISION</id><enabled>Y</enabled><name>OBJECT_REVISION</name></field><field><id>PARENT_CHANNEL_ID</id><enabled>Y</enabled><name>PARENT_CHANNEL_ID</name></field><field><id>ROOT_CHANNEL_ID</id><enabled>Y</enabled><name>ROOT_CHANNEL_ID</name></field></channel-log-table><step-log-table><connection/><schema/><table/><timeout_days/><field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>LOG_FIELD</id><enabled>N</enabled><name>LOG_FIELD</name></field></step-log-table><metrics-log-table><connection/><schema/><table/><timeout_days/><field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>METRICS_DATE</id><enabled>Y</enabled><name>METRICS_DATE</name></field><field><id>METRICS_CODE</id><enabled>Y</enabled><name>METRICS_CODE</name></field><field><id>METRICS_DESCRIPTION</id><enabled>Y</enabled><name>METRICS_DESCRIPTION</name></field><field><id>METRICS_SUBJECT</id><enabled>Y</enabled><name>METRICS_SUBJECT</name></field><field><id>METRICS_TYPE</id><enabled>Y</enabled><name>METRICS_TYPE</name></field><field><id>METRICS_VALUE</id><enabled>Y</enabled><name>METRICS_VALUE</name></field></metrics-log-table></log><maxdate><connection/><table/><field/><offset>0.0</offset><maxdiff>0.0</maxdiff></maxdate><size_rowset>10000</size_rowset><sleep_time_empty>50</sleep_time_empty><sleep_time_full>50</sleep_time_full><unique_connections>N</unique_connections><feedback_shown>Y</feedback_shown><feedback_size>50000</feedback_size><using_thread_priorities>Y</using_thread_priorities><shared_objects_file/><capture_step_performance>N</capture_step_performance><step_performance_capturing_delay>1000</step_performance_capturing_delay><step_performance_capturing_size_limit>100</step_performance_capturing_size_limit><dependencies></dependencies><partitionschemas></partitionschemas><slaveservers></slaveservers><clusterschemas></clusterschemas><created_user>-</created_user><created_date>2021/11/18 16:00:56.529</created_date><modified_user>-</modified_user><modified_date>2021/11/18 16:00:56.529</modified_date><key_for_session_key/><is_key_private>N</is_key_private></info><notepads></notepads><order><hop><from>Excel输入</from><to>Excel输出</to><enabled>Y</enabled></hop></order><step><name>Excel输入</name><type>ExcelInput</type><description/><distribute>Y</distribute><custom_distribution/><copies>1</copies><partitioning><method>none</method><schema_name/></partitioning><header>Y</header><noempty>Y</noempty><stoponempty>N</stoponempty><filefield/><sheetfield/><sheetrownumfield/><rownumfield/><sheetfield/><filefield/><limit>0</limit><encoding/><add_to_result_filenames>Y</add_to_result_filenames><accept_filenames>N</accept_filenames><accept_field/><accept_stepname/><file><name>F:\kette_test\input\person.xlsx</name><filemask/><exclude_filemask/><file_required>N</file_required><include_subfolders>N</include_subfolders></file><fields><field><name>id</name><type>String</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field><field><name>name</name><type>String</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field><field><name>age</name><type>Integer</type><length>-1</length><precision>-1</precision><trim_type>none</trim_type><repeat>N</repeat><format/><currency/><decimal/><group/></field></fields><sheets></sheets><strict_types>N</strict_types><error_ignored>N</error_ignored><error_line_skipped>N</error_line_skipped><bad_line_files_destination_directory/><bad_line_files_extension>warning</bad_line_files_extension><error_line_files_destination_directory/><error_line_files_extension>error</error_line_files_extension><line_number_files_destination_directory/><line_number_files_extension>line</line_number_files_extension><shortFileFieldName/><pathFieldName/><hiddenFieldName/><lastModificationTimeFieldName/><uriNameFieldName/><rootUriNameFieldName/><extensionFieldName/><sizeFieldName/><spreadsheet_type>POI</spreadsheet_type><attributes/><cluster_schema/><remotesteps><input></input><output></output></remotesteps><GUI><xloc>416</xloc><yloc>176</yloc><draw>Y</draw></GUI></step><step><name>Excel输出</name><type>ExcelOutput</type><description/><distribute>Y</distribute><custom_distribution/><copies>1</copies><partitioning><method>none</method><schema_name/></partitioning><header>Y</header><footer>N</footer><encoding/><append>N</append><add_to_result_filenames>Y</add_to_result_filenames><file><name>F:\kette_test\output\excel输出.xls</name><extention/><do_not_open_newfile_init>N</do_not_open_newfile_init><create_parent_folder>N</create_parent_folder><split>N</split><add_date>N</add_date><add_time>N</add_time><SpecifyFormat>N</SpecifyFormat><date_time_format/><sheetname>Sheet1</sheetname><autosizecolums>N</autosizecolums><nullisblank>N</nullisblank><protect_sheet>N</protect_sheet><password>Encrypted </password><splitevery>0</splitevery><usetempfiles>N</usetempfiles><tempdirectory/></file><template><enabled>N</enabled><append>N</append><filename>template.xls</filename></template><fields><field><name>id</name><type>String</type><format/></field><field><name>name</name><type>String</type><format/></field><field><name>age</name><type>Integer</type><format>0</format></field></fields><custom><header_font_name>arial</header_font_name><header_font_size>10</header_font_size><header_font_bold>N</header_font_bold><header_font_italic>N</header_font_italic><header_font_underline>no</header_font_underline><header_font_orientation>horizontal</header_font_orientation><header_font_color>black</header_font_color><header_background_color>none</header_background_color><header_row_height>255</header_row_height><header_alignment>left</header_alignment><header_image/><row_font_name>arial</row_font_name><row_font_size>10</row_font_size><row_font_color>black</row_font_color><row_background_color>none</row_background_color></custom><attributes/><cluster_schema/><remotesteps><input></input><output></output></remotesteps><GUI><xloc>544</xloc><yloc>176</yloc><draw>Y</draw></GUI></step><step_error_handling></step_error_handling><slave-step-copy-partition-distribution></slave-step-copy-partition-distribution><slave_transformation>N</slave_transformation><attributes/>
</transformation>

通过ktr文件写交换代码相关推荐

  1. phpcms文件夹plugin调用怎么写路径 - 代码篇

    phpcms文件夹statics/plugin/调用怎么写路径 - 代码篇 众所周知,用过phpcms框架的基本都熟悉APP_PATH的路径是http://localhost/,所以调用网站根目录ww ...

  2. java 保存的代码怎么写_java实现写入并保存txt文件的示例代码

    java实现写入并保存txt文件的示例代码 发布时间:2020-04-30 15:14:07 来源:亿速云 阅读:110 作者:小新 这篇文章主要为大家详细介绍了java实现写入并保存txt文件的示例 ...

  3. 揭秘:一个月不摸鱼能写多少代码?

    作者 | 老鱼皮 来源 | 程序员鱼皮(ID:coder_yupi) 猜猜写了多少行?都写了哪些语言呢? 时间过得真是太快了,又到月底了.对于程序员来说,总结还是挺重要的,我也一直保持着一个习惯,就是 ...

  4. python写了代码_Python写代码的用法建议

    1.Mutable and immutable types Python有两种内置或用户定义的类型 可变类型是允许就地修改内容的类型.典型的可变列表是列表和词典:所有列表都有变异方法,如 list.a ...

  5. python读文件写文件-python 文件读写操作

    读文件 打开一个文件用open()方法(open()返回一个文件对象,它是可迭代的): >>> f = open('test.txt', 'r') r表示是文本文件,rb是二进制文件 ...

  6. 【低代码】手写低代码中的编译器/翻译器

    编译器.解释器 相信计算机的同学对这两个词一定不陌生,从学计算机开始,我们就知道了计算机是二进制的世界,而我们用高级语言编写的代码计算机是无法理解的,编译器就是将我们编写的代码编译成计算机可以执行的二 ...

  7. Python写的代码打包成.exe可执行文件

    Python写的代码打包成.exe可执行文件 1. 安装pyinstaller 2. [在线生成icon](http://www.ico51.cn/) 3. 打包命令 pyinstaller -i x ...

  8. python怎么发送代码文件_python 通过 socket 发送文件的实例代码

    目录结构: client: #!/usr/bin/env python # -*-coding:utf-8 -*- import socket, struct, json download_dir = ...

  9. 不写一行代码,也能玩转Kaggle竞赛?

    整理 | Jane 出品 | AI科技大本营(ID:rgznai100) [导读]AI科技大本营会给大家分享一些 Kaggle 上的资源,如 Kaggle 开放的数据集,也会分享一些好的竞赛方案或有意 ...

  10. 哈哈哈,这个教人写烂代码的项目在 GitHub 上火了...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 如果说到什么是好代码,我们肯定都能说出一堆规则,例如使用一致的格式 ...

最新文章

  1. 微软副总裁Bob Muglia对Silverlight的公开道歉信
  2. 解决写入InfluxDB时,报unbalanced quotes的问题
  3. Dell 2950服务器CPU-E1422错误解决方法
  4. Python 代码性能优化技巧
  5. linux常见面试题
  6. SpringCloud Sleuth分布式请求链路追踪
  7. Flink : Flink run yarn 报错 could not build the program from jar file -ynm
  8. 2000年一元钱牡丹图案现在值钱吗?
  9. Oracle 分析函数的使用(主要是rollup用法)
  10. DPDK初始化分析(三)
  11. Android实现计算器布局(线性布局)
  12. 市场调研策划书_市场调研计划书3篇(资料4)
  13. T229473 D. 背单词的小智(二分)
  14. 博客园增加Live2D看板娘教程,超级简单,一看就懂
  15. 【USACO 2020 January Silver】Loan Repayment
  16. 关于根轨迹对于控制系统的一点理解
  17. 常数变易法的“前世今生”
  18. 设计模式—简单工厂模式
  19. 如何获得CSDN积分(转)
  20. 广西省谷歌地球高程DEM等高线下载

热门文章

  1. 数据分析——帆软report
  2. TSE无线通信(铺垫)
  3. 笔记本电脑开机后,屏幕无反应,插入的鼠标和键盘无灯亮起
  4. 2021-2027全球与中国卸扣式绝缘子市场现状及未来发展趋势
  5. codingdojo kata 之fizzbuzz
  6. 墨魂服务器维修,墨魂琅轩路线怎么选最新游戏攻略
  7. 目标检测 | 丰富特征导向Refinement Network用于目标检测(附github源码)
  8. 浅谈数据中心 IT 机房的空气调节(下篇)-制冷中断
  9. 匹配 网络 Q值 带宽
  10. 水溶性量子点CdSe/ZnS