Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
cfsimplicity committed Nov 27, 2023
2 parents 78ca81c + 214995b commit ef2e8f6
Show file tree
Hide file tree
Showing 33 changed files with 101 additions and 117 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## 3.12.0 - 27 November 2023

- Enhancements
-\#346 Add writeCsv()

- Fixes
-\#347/\#348 Avoid Perl/Java regex engine incompatibilities

- Maintenance
-\#349 Upgrade POI to 5.2.5
-\#350 Upgrade excel-streaming-reader to 4.2.1

## 3.11.1 - 15 November 2023

- \#345 readCsv(): Commons CSV boolean options should default to true
Expand All @@ -13,7 +25,7 @@
- \#339 csvToQuery() ignores trim setting when reading from file

- Maintenance
- \#334 Upgrade excel-streaming-reader to 4.2.0
- \#344 Upgrade excel-streaming-reader to 4.2.0

## 3.10.0 - 29 September 2023

Expand Down
2 changes: 1 addition & 1 deletion ModuleConfig.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ component{
this.author = "Julian Halliwell";
this.webURL = "https://github.com/cfsimplicity/spreadsheet-cfml";
this.description = "CFML Spreadsheet Library";
this.version = "3.11.1";
this.version = "3.12.0";
this.autoMapModels = false;

function configure(){
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ You may wish to place the spreadsheet library files in a central location with a
* [workbookFromCsv](https://github.com/cfsimplicity/spreadsheet-cfml/wiki/workbookFromCsv)
* [workbookFromQuery](https://github.com/cfsimplicity/spreadsheet-cfml/wiki/workbookFromQuery)
* [writeFileFromQuery](https://github.com/cfsimplicity/spreadsheet-cfml/wiki/writeFileFromQuery)
* [writeCsv](https://github.com/cfsimplicity/spreadsheet-cfml/wiki/writeCsv)
* [writeToCsv](https://github.com/cfsimplicity/spreadsheet-cfml/wiki/writeToCsv)

### Enhanced Read() method
Expand Down
54 changes: 26 additions & 28 deletions Spreadsheet.cfc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
component accessors="true"{

//"static"
property name="version" default="3.11.1-develop" setter="false";
property name="osgiLibBundleVersion" default="5.2.4.1" setter="false"; //first 3 octets = POI version; increment 4th with other jar updates
property name="version" default="3.12.0" setter="false";
property name="osgiLibBundleVersion" default="5.2.5.1" setter="false"; //first 3 octets = POI version; increment 4th with other jar updates
property name="osgiLibBundleSymbolicName" default="spreadsheet-cfml" setter="false";
property name="exceptionType" default="cfsimplicity.spreadsheet" setter="false";
//configurable
Expand Down Expand Up @@ -1097,14 +1097,13 @@ component accessors="true"{
}

/* row order is not guaranteed if using more than one thread */
public string function queryToCsv( required query query, boolean includeHeaderRow=false, string delimiter=",", numeric threads=1 ){
var data = getCsvHelper().queryToArrayForCsv( arguments.query, arguments.includeHeaderRow, arguments.threads );
var builder = getStringHelper().newJavaStringBuilder();
var csvFormat = getCsvHelper().getFormatForPrinting( arguments.delimiter );
createJavaObject( "org.apache.commons.csv.CSVPrinter" )
.init( builder, csvFormat )
.printRecords( data );
return builder.toString().Trim();
public string function queryToCsv( required query query, boolean includeHeaderRow=false, string delimiter=",", numeric threads=0 ){
return writeCsv()
.fromData( arguments.query )
.withQueryColumnsAsHeader( arguments.includeHeaderRow )
.withDelimiter( arguments.delimiter )
.withParallelThreads( arguments.threads )
.execute();
}

public any function read(
Expand Down Expand Up @@ -1170,17 +1169,15 @@ component accessors="true"{
var generatedQuery = getSheetHelper().sheetToQuery( argumentCollection=args );
if( arguments.format == "query" )
return generatedQuery;
args = { query: generatedQuery };
if( arguments.KeyExists( "headerRow" ) ){
args.headerRow = arguments.headerRow;
args.includeHeaderRow = arguments.includeHeaderRow;
}
if( arguments.format == "csv" ){
args.delimiter = arguments.csvDelimiter;
return queryToCsv( argumentCollection=args );
return writeCsv()
.fromData( generatedQuery )
.withQueryColumnsAsHeader( arguments.includeHeaderRow )
.withDelimiter( arguments.csvDelimiter )
.execute();
}
// format = html
return getQueryHelper().queryToHtml( argumentCollection=args );
return getQueryHelper().queryToHtml( generatedQuery, arguments.includeHeaderRow );
}

public binary function readBinary( required workbook ){
Expand Down Expand Up @@ -1245,17 +1242,15 @@ component accessors="true"{
var generatedQuery = getStreamingReaderHelper().readFileIntoQuery( arguments.src, builderOptions, sheetToQueryArgs );
if( arguments.format == "query" )
return generatedQuery;
var exportArgs = { query: generatedQuery };
if( arguments.KeyExists( "headerRow" ) ){
exportArgs.headerRow = arguments.headerRow;
exportArgs.includeHeaderRow = arguments.includeHeaderRow;
}
if( arguments.format == "csv" ){
exportArgs.delimiter = arguments.csvDelimiter;
return queryToCsv( argumentCollection=exportArgs );
return writeCsv()
.fromData( generatedQuery )
.withQueryColumnsAsHeader( arguments.includeHeaderRow )
.withDelimiter( arguments.csvDelimiter )
.execute();
}
// format = html
return getQueryHelper().queryToHtml( argumentCollection=exportArgs );
return getQueryHelper().queryToHtml( generatedQuery, arguments.includeHeaderRow );
}

public Spreadsheet function removePrintGridlines( required workbook ){
Expand Down Expand Up @@ -1769,8 +1764,11 @@ component accessors="true"{
,includeHeaderRow=arguments.includeHeaderRow
,makeColumnNamesSafe=true //doesn't affect the output: avoids ACF clunky workaround in _QueryNew()
);
var csv = queryToCsv( query=data, delimiter=arguments.delimiter );
FileWrite( arguments.filepath, csv );
writeCsv()
.fromData( data )
.toFile( arguments.filepath )
.withDelimiter( arguments.delimiter )
.execute();
return this;
}

Expand Down
2 changes: 1 addition & 1 deletion box.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name" : "Spreadsheet CFML",
"slug" : "spreadsheet-cfml",
"version" : "3.11.1",
"version" : "3.12.0",
"shortDescription" : "CFML spreadsheet library",
"author" : "Julian Halliwell",
"location" : "forgeboxStorage",
Expand Down
14 changes: 14 additions & 0 deletions build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,37 @@ https://mvnrepository.com
Here is the current list of required jars:

* commons-codec
https://mvnrepository.com/artifact/commons-codec/commons-codec
* commons-collections4
https://mvnrepository.com/artifact/org.apache.commons/commons-collections4
* commons-compress
https://mvnrepository.com/artifact/org.apache.commons/commons-compress
* commons-io
https://mvnrepository.com/artifact/commons-io/commons-io
* commons-math3
https://mvnrepository.com/artifact/org.apache.commons/commons-math3
* log4j-api
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api
* poi
https://repo1.maven.org/maven2/org/apache/poi/poi/
* poi-ooxml
https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml/
* poi-ooxml-full
https://repo1.maven.org/maven2/org/apache/poi/poi-ooxml-full
* SparseBitSet
https://mvnrepository.com/artifact/com.zaxxer/SparseBitSet
* xmlbeans
https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans

## Other dependency binaries

The following jars are not POI dependencies but are required by the Spreadsheet Library:

* commons-csv
https://mvnrepository.com/artifact/org.apache.commons/commons-csv
* excel-streaming-reader
https://mvnrepository.com/artifact/com.github.pjfanning/excel-streaming-reader
* slf4j-api
https://mvnrepository.com/artifact/org.slf4j/slf4j-api

All available from https://mvnrepository.com
20 changes: 10 additions & 10 deletions build/lib-osgi.mf
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Spreadsheet CFML
Bundle-SymbolicName: spreadsheet-cfml
Bundle-Version: 5.2.4.1
Bundle-Version: 5.2.5.1
Bundle-ClassPath: commons-codec-1.16.0.jar,
commons-collections4-4.4.jar,
commons-compress-1.24.0.jar,
commons-compress-1.25.0.jar,
commons-csv-1.10.0.jar,
commons-io-2.13.0.jar,
commons-io-2.15.0.jar,
commons-math3-3.6.1.jar,
excel-streaming-reader-4.2.0.jar,
log4j-api-2.20.0.jar,
poi-5.2.4.jar,
poi-ooxml-5.2.4.jar,
poi-ooxml-full-5.2.4.jar,
slf4j-api-1.7.36.jar,
excel-streaming-reader-4.2.1.jar,
log4j-api-2.22.0.jar,
poi-5.2.5.jar,
poi-ooxml-5.2.5.jar,
poi-ooxml-full-5.2.5.jar,
slf4j-api-2.0.9.jar,
SparseBitSet-1.3.jar,
spreadsheet-cfml.jar,
xmlbeans-5.1.1.jar
xmlbeans-5.2.0.jar
4 changes: 2 additions & 2 deletions build/task.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ component{
property name="classpathDirectories";
property name="libPath";
property name="minimumSupportedJvmVersion" default="8";//update this as necessary
property name="ooxmlVersion" default="5.2.4";
property name="ooxmlVersion" default="5.2.5";
property name="rootPath";
property name="srcPath";
property name="tempDirectoryPath";
property name="xmlBeansVersion" default="5.1.1";
property name="xmlBeansVersion" default="5.2.0";

void function run(){
variables.tempDirectoryPath = getCWD() & "temp/";
Expand Down
44 changes: 0 additions & 44 deletions helpers/csv.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,6 @@ component extends="base"{
.build();
}

any function getFormatForPrinting( required string delimiter ){
if( delimiterIsTab( arguments.delimiter ) )
return getFormatObject( "TDF" );
var format = getFormatObject( "EXCEL" );
return format.builder().setDelimiter( arguments.delimiter ).build();
}

array function getColumnNames( required boolean firstRowIsHeader, required array data, required numeric maxColumnCount ){
var result = [];
if( arguments.firstRowIsHeader )
Expand All @@ -38,30 +31,6 @@ component extends="base"{
return result;
}

/* row order is not guaranteed if using more than one thread */
array function queryToArrayForCsv( required query query, required boolean includeHeaderRow, numeric threads=1 ){
var result = [];
var columns = getQueryHelper()._QueryColumnArray( arguments.query );
if( arguments.includeHeaderRow )
result.Append( columns );
if( ( arguments.threads > 1 ) && !library().engineSupportsParallelLoopProcessing() )
getExceptionHelper().throwParallelOptionNotSupportedException();
if( arguments.threads > 1 ){
arguments.query.Each(
function( row ){
result.Append( getQueryRowValues( row, columns ) );
}
,true
,arguments.threads
);
return result;
}
for( var row IN arguments.query ){
result.Append( getQueryRowValues( row, columns ) );
}
return result;
}

struct function parseFromString( required string csvString, required boolean trim, required any format ){
if( arguments.trim )
arguments.csvString = arguments.csvString.Trim();
Expand Down Expand Up @@ -108,17 +77,4 @@ component extends="base"{
return result;
}

private array function getQueryRowValues( required row, required array columns ){
var rowValues = [];
for( var column IN arguments.columns ){
var cellValue = arguments.row[ column ];
if( getDateHelper().isDateObject( cellValue ) )
cellValue = DateTimeFormat( cellValue, library().getDateFormats().DATETIME );
if( IsValid( "integer", cellValue ) )
cellValue = JavaCast( "string", cellValue );// prevent CSV writer converting 1 to 1.0
rowValues.Append( cellValue );
};
return rowValues;
}

}
2 changes: 1 addition & 1 deletion helpers/headerImage.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ component extends="base"{
getFileHelper().closeLocalFileOrStream( local, "imageInputStream" );
}
var newShapeElement = createNewHeaderImageVMLShape( pictureRelationID, vmlPosition, imageDimension );
headerImageXML = headerImageXML.ReReplaceNoCase( "(<\/[\w:]*xml>)", newShapeElement & "\1" );
headerImageXML = headerImageXML.ReplaceAll( "(?i)(<\/[\w:]*xml>)", newShapeElement & "$1" );//Use java regex for group reference consistency
headerImageVml.setXml( headerImageXML );
//create the sheet/vml relation
var xssfVmlRelation = library().createJavaObject( "org.apache.poi.xssf.usermodel.XSSFRelation" ).VML_DRAWINGS;
Expand Down
5 changes: 2 additions & 3 deletions helpers/query.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,10 @@ component extends="base"{
return arguments.queryColumnTypes;
}

string function queryToHtml( required query query, numeric headerRow, boolean includeHeaderRow=false ){
string function queryToHtml( required query query, boolean includeHeaderRow=false ){
var result = getStringHelper().newJavaStringBuilder();
var columns = _QueryColumnArray( arguments.query );
var generateHeaderRow = ( arguments.includeHeaderRow && arguments.KeyExists( "headerRow" ) && Val( arguments.headerRow ) );
if( generateHeaderRow ){
if( arguments.includeHeaderRow ){
result.Append( "<thead>" );
result.Append( generateHtmlRow( columns, true ) );
result.Append( "</thead>" );
Expand Down
2 changes: 1 addition & 1 deletion helpers/range.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ component extends="base"{
}

string function convertRangeReferenceToAbsoluteAddress( required string rangeReference ){
return arguments.rangeReference.REReplace( "([A-Za-z]+|\d+)", "$\1", "ALL" ).UCase();
return arguments.rangeReference.ReplaceAll( "([A-Za-z]+|\d+)", "\$$1" ).UCase(); //Use java regex for group reference consistency
}

/* Private */
Expand Down
Binary file modified lib-osgi.jar
Binary file not shown.
Binary file removed lib/commons-compress-1.24.0.jar
Binary file not shown.
Binary file added lib/commons-compress-1.25.0.jar
Binary file not shown.
Binary file removed lib/commons-io-2.13.0.jar
Binary file not shown.
Binary file added lib/commons-io-2.15.0.jar
Binary file not shown.
Binary file not shown.
Binary file removed lib/log4j-api-2.20.0.jar
Binary file not shown.
Binary file added lib/log4j-api-2.22.0.jar
Binary file not shown.
Binary file renamed lib/poi-5.2.4.jar → lib/poi-5.2.5.jar
Binary file not shown.
Binary file renamed lib/poi-ooxml-5.2.4.jar → lib/poi-ooxml-5.2.5.jar
Binary file not shown.
Binary file not shown.
Binary file removed lib/slf4j-api-1.7.36.jar
Binary file not shown.
Binary file added lib/slf4j-api-2.0.9.jar
Binary file not shown.
Binary file modified lib/spreadsheet-cfml.jar
Binary file not shown.
Binary file renamed lib/xmlbeans-5.1.1.jar → lib/xmlbeans-5.2.0.jar
Binary file not shown.
10 changes: 7 additions & 3 deletions objects/WriteCsv.cfc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
component extends="BaseCsv" accessors="true"{

property name="data" setter="false";
property name="parallelThreadsToUse" type="numeric" default=1 setter="false";
property name="parallelThreadsToUse" type="numeric" default=0 setter="false";
property name="useQueryColumnsAsHeader" type="boolean" default="false" setter="false";
property name="useStructKeysAsHeader" type="boolean" default="false" setter="false";

Expand All @@ -25,7 +25,11 @@ component extends="BaseCsv" accessors="true"{
}

public WriteCsv function withParallelThreads( numeric numberOfThreads=2 ){
/* WARNING: can have unexpected results */
/* WARNING: can have unexpected results such as rows out of order or system crashes. USE WITH CARE. */
if( arguments.numberOfThreads < 2 ){
variables.parallelThreadsToUse = 0;
return this;
}
if( !variables.library.engineSupportsParallelLoopProcessing() )
variables.library.getExceptionHelper().throwParallelOptionNotSupportedException();
variables.parallelThreadsToUse = Int( arguments.numberOfThreads );
Expand Down Expand Up @@ -178,7 +182,7 @@ component extends="BaseCsv" accessors="true"{
}

private boolean function useParallelThreads(){
return variables.library.engineSupportsParallelLoopProcessing() && ( variables.parallelThreadsToUse > 1 );
return ( variables.library.engineSupportsParallelLoopProcessing() && ( variables.parallelThreadsToUse > 1 ) );
}

private array function _StructValueArray( required struct data ){
Expand Down
2 changes: 1 addition & 1 deletion test/specs/dateFormats.cfm
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe( "dateFormats customisability",function(){
var actual = s.read( src=path, format="html" );
var expected = "<tbody><tr><td>a</td><td>b</td></tr><tr><td>1</td><td>04/01/2015 12:0:0</td></tr><tr><td>04/01/2015 1:1:1</td><td>2</td></tr></tbody>";
expect( actual ).toBe( expected );
expected = 'a,b#newline#1,04/01/2015 12:0:0#newline#04/01/2015 1:1:1,2';
expected = 'a,b#newline#1,04/01/2015 12:0:0#newline#04/01/2015 1:1:1,2#newline#';
actual = s.read( src=path, format="csv" );
expect( actual ).toBe( expected );
});
Expand Down
Loading

0 comments on commit ef2e8f6

Please sign in to comment.