Topic: Libxl
It can read and write excel data.But not free.
For discussions of all Approximatrix products and related software
You are not logged in. Please login or register.
Approximatrix Forums → Package Requests → Libxl
It can read and write excel data.But not free.
It's unclear from the license whether we can redistribute the trial versions. It could be complicated. They do already provide a standards-non-compliant Fortran module source file that you can use as-is, though.
Hi Weixing1531,
I've copied a FORTRAN program for reading CSV files from the internet (see listing below). Although it doesn't solve your problem, it does get you about half the way there. Using this listing as an example, you or someone else may be able to add code to write to a CSV file. Although the listing below is only for three columns of data, it could be expanded to accommodate more columns of data. The original code was only for two columns of data; I've modified it to include three columns of data.
Dr.Frank
!-----------------------------------------------------------------------
! Tek-Tips Forums (24 Jun 10)
! https://www.tek-tips.com/viewthread.cfm?qid=1609257
! Save your Excel as CSV-file (Comma Separated Values) and
! process it using fortran.
!
! Modified to read three columns of csv file data
! Dr.Frank (10-10-2022)
!-----------------------------------------------------------------------
module csv_mod
type csv_header_line
character(10) :: c01 ! column 01 header
character(10) :: c02 ! column 02 header
character(10) :: c03 ! column 03 header
end type csv_header_line
type csv_data_line
integer :: c01 ! column 01: id
character(10):: c02 ! column 02: name
real :: c03 ! column 03: age
end type csv_data_line
contains
subroutine parse_header(separator, line, header)
character(*), intent(in) :: separator, line
type(csv_header_line), intent(out) :: header
integer :: separator_pos, next_pos
!separator position
separator_pos = index(line, separator) - 1
!extract first heading
header%c01 = adjustl(trim(line(:separator_pos)))
!splice next heading (FWP)
separator_pos = separator_pos + 2
next_pos = separator_pos + index( line(separator_pos:), separator ) - 2
header%c02 = adjustl(trim(line(separator_pos:next_pos)))
!splice next heading (FWP)
separator_pos = next_pos + 2
next_pos = separator_pos + len_trim( line(separator_pos:) ) - 1
header%c03 = adjustl(trim(line(separator_pos:next_pos)))
end subroutine parse_header
subroutine parse_data(separator, line, dta, nr)
character(*), intent(in) :: separator, line
integer, intent(in) :: nr
type(csv_data_line), dimension(:), intent(inout) :: dta
integer :: separator_pos, next_pos
!separator position
separator_pos = index(line, separator) - 1
! convert substring into integer number dta(nr)%c01
read (line(:separator_pos),'(I3)') dta(nr)%c01
!splice next data and save into dta(nr)%c02 (FWP)
!separator position
separator_pos = separator_pos + 2
next_pos = separator_pos + index( line(separator_pos:), separator ) - 2
dta(nr)%c02 = adjustl(trim(line(separator_pos:next_pos)))
!splice next data and save into dta(nr)%c03 (FWP)
!separator position
separator_pos = next_pos + 2
next_pos = separator_pos + len_trim( line(separator_pos:) ) - 1
! convert substring into real number
read (line(separator_pos:next_pos),'(F8.3)') dta(nr)%c03
end subroutine parse_data
end module csv_mod
program csv_3Col_read
use csv_mod
implicit none
integer, parameter :: max_csv_lines = 100 ! max number of lines in CSV
integer stat, line_nr, nr, j, computed_number
character(80) :: line
type(csv_header_line) :: csv_header
type(csv_data_line), dimension(max_csv_lines) :: csv_data
integer, parameter :: csv_columns = 3 ! number of columns in CSV
character(1) :: separator = ','
character(80) :: filename
filename = 'test_3_cols.csv'
! open file
open (1, file=filename, status='old', iostat=stat)
if (stat .ne. 0) then
write(*,*) 'File cannot be opened !'
go to 99
end if
write(*,*) 'Reading CSV-file...'
! process file
line_nr = 0
do while (.true.)
read(1, '(A)', end=99) line
line_nr = line_nr + 1
if (line_nr .eq. 1) then
call parse_header(separator, adjustl(trim(line)), csv_header)
else
! if line_nr > 1 then parse data line
nr = line_nr - 1
call parse_data(separator, adjustl(trim(line)), csv_data, nr)
end if
end do
! close file
99 continue
close(1)
!write(*,*) 'Done.'
write(*,*) 'Number of all lines found in CSV = ', line_nr
write(*,*) 'Number of data lines found in CSV = ', nr
! write the data
write(*, '(A)') '****************************************'
write(*,'(2X,A3, 1X,A10, 1X,A10, 2X,A10)') csv_header%c01, &
adjustr(csv_header%c02), &
adjustr(csv_header%c03), &
'NINT(age)'
write(*, '(A)') '****************************************'
do j = 1, nr
computed_number = NINT(csv_data(j)%c03)
write (*,'(1X,I3, 2X,A10, 5X,F8.3, 2X,I3)') csv_data(j)%c01, &
csv_data(j)%c02, &
csv_data(j)%c03, &
computed_number
end do
write(*, '(A)') '****************************************'
end program csv_3Col_read
!OUTPUT:
! Reading CSV-file...
! Number of all lines found in CSV = 20
! Number of data lines found in CSV = 19
!****************************************
! id first_name age NINT(age)
!****************************************
! 1 Julie 80.244 80
! 2 Jose 11.569 12
! 3 Lois 12.339 12
! 4 Walter 63.173 63
! 5 Timothy 57.063 57
! 6 Barbara 79.705 80
! 7 Douglas 19.347 19
! 8 Tina 16.909 17
! 9 Gregory 67.749 68
! 10 Larry 43.705 44
! 11 Tina 9.931 10
! 12 Kelly 72.657 73
! 13 Marilyn 10.901 11
! 14 Gregory 9.966 10
! 15 Earl 10.875 11
! 16 Evelyn 33.268 33
! 17 Carol 54.498 54
! 18 Alice 2.505 3
! 19 Randy 39.775 40
!****************************************
!INPUT CSV DATA FILE:
id,first_name,age
1,Julie,80.244
2,Jose,11.569
3,Lois,12.339
4,Walter,63.173
5,Timothy,57.063
6,Barbara,79.705
7,Douglas,19.347
8,Tina,16.909
9,Gregory,67.749
10,Larry,43.705
11,Tina,9.931
12,Kelly,72.657
13,Marilyn,10.901
14,Gregory,9.966
15,Earl,10.875
16,Evelyn,33.268
17,Carol,54.498
18,Alice,2.505
19,Randy,39.775
There is a csv module in GitHub.
You can search it.
Approximatrix Forums → Package Requests → Libxl
Powered by PunBB, supported by Informer Technologies, Inc.