Reputation: 21
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:
pdftk
command is available in the system's PATH
by running which pdftk
in the terminal.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
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:
one.pdf
two.pdf
cat
output
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:
one.pdf two.pdf
cat
output
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