SANONICHAN
SANONICHAN

Reputation: 21

PDF Merging with Elixir and pdftk with Implementation?

I am working on an Elixir project that involves merging PDF files using the pdftk command-line tool. I have written a function in my Elixir module, PdfMerger.MergePdfs, to merge PDFs using the pdftk command. However, when I call this function with input files, it returns an error.

defmodule PdfMerger.MergePdfs do
  def method(input_files, output_file) do
    if pdftk_installed?() do
      merge_pdfs(input_files, output_file)
    else
      IO.puts("Error: pdftk is not installed.")
    end
  end

  defp command_exists?(command) do
    System.cmd("which", [command]) == {"/usr/bin/#{command}\n", 0}
  end

  defp pdftk_installed? do
    command_exists?("pdftk")
  end

  defp merge_pdfs(input_files, output_file) do
    input_files_string = Enum.join(input_files, " ")
    output_file = Path.expand(output_file)

    files_exist? = Enum.all?(input_files, &File.exists?/1)

    if files_exist? do
      {output, status} =
        System.cmd("pdftk", ["#{input_files_string}", "cat", "output", "#{output_file}"])

      case status do
        0 ->
          IO.puts("PDFs merged successfully.")

        _ ->
          IO.puts("Error: PDF merging failed.")
      end
    else
      IO.puts("Error: One or more input files do not exist.")
    end
  end
end

The result:

Error: Unable to find file.
Error: Failed to open input PDF file: 
   /zip_files_api/folder_test/3efb2f00-2be4-11ee-8303-a463a172bc38/file1.pdf /zip_files_api/folder_test/3efb2f00-2be4-11ee-8303-a463a172bc38/file2.pdf
Errors encountered.  No output created.
Done.  Input errors, so no output created.

I have verified that the input_files list contains valid paths to existing PDF files, and the output_file is also a valid path where I have write permissions.

The merge_pdfs/2 function is intended to join the PDF files using the pdftk command. I'm using System.cmd/3 to execute the command with the appropriate arguments.

What I've Tried:

Expected Outcome:

I expect the PdfMerger.MergePdfs.method/2 function to successfully merge the input PDF files into the specified output file, just like it works when I run the pdftk command directly in the terminal.

Please let me know if you need any additional information or if there's anything else I can provide to help diagnose and resolve the issue.

To summarize, the goal was to identify and resolve the error that occurred when running the PdfMerger.MergePdfs.method/2 function, so that the function could successfully merge the input PDF files into the specified output file.

Upvotes: 0

Views: 202

Answers (1)

legoscia
legoscia

Reputation: 41578

Try changing the System.cmd call to this:

System.cmd("pdftk", input_files ++ ["cat", "output", output_file])

That is, pass each input file as a separate command line argument, instead of concatenating the file names and passing them all as a single argument.


The difference to what you've tried in the terminal is that the shell splits command line arguments at spaces. So in this command:

pdftk one.pdf two.pdf cat output three.pdf

there are five command line arguments:

  1. one.pdf
  2. two.pdf
  3. cat
  4. output
  5. three.pdf

By contrast, when running this piece of Elixir code:

input_files = ["one.pdf", "two.pdf"]
input_files_string = Enum.join(input_files, " ")
output_file = "three.pdf"
System.cmd("pdftk", ["#{input_files_string}", "cat", "output", "#{output_file}"])

there are four arguments, because System.cmd passes the arguments given in the list, no more, no less:

  1. one.pdf two.pdf
  2. cat
  3. output
  4. three.pdf

This fails because there is no file called one.pdf two.pdf, with a space in the middle of the file name. You can get the same result in the terminal by quoting the input files:

pdftk "one.pdf two.pdf" cat output three.pdf

Upvotes: 1

Related Questions