Topic: Libxl

It can read and write excel data.But not free.

Re: Libxl

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.

Jeff Armstrong
Approximatrix, LLC

Re: Libxl

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

Re: Libxl

There is a csv module in GitHub.
You can search it.