<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Convertica</title>
    <description>The latest articles on DEV Community by Convertica (@convertica_01bef32536e9e7).</description>
    <link>https://dev.to/convertica_01bef32536e9e7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4028779%2Fa820df92-5a57-493f-8ff6-45f7a950a38a.png</url>
      <title>DEV Community: Convertica</title>
      <link>https://dev.to/convertica_01bef32536e9e7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/convertica_01bef32536e9e7"/>
    <language>en</language>
    <item>
      <title>Automating the PDF Conversions You Keep Doing by Hand</title>
      <dc:creator>Convertica</dc:creator>
      <pubDate>Tue, 14 Jul 2026 13:48:34 +0000</pubDate>
      <link>https://dev.to/convertica_01bef32536e9e7/automating-the-pdf-conversions-you-keep-doing-by-hand-4d0d</link>
      <guid>https://dev.to/convertica_01bef32536e9e7/automating-the-pdf-conversions-you-keep-doing-by-hand-4d0d</guid>
      <description>&lt;p&gt;Most PDF work is a one-off: a file lands, you convert it, you move on. But some of it repeats. A folder of scanned invoices every Monday. Statements that need to become spreadsheets before month-end. Reports that arrive as PDF and have to go out as Word. If you are doing the same conversion by hand every week, that is a job for a script, not a person.&lt;/p&gt;

&lt;p&gt;Here is how I moved those repeat conversions off my plate.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the ten-second check that saves you
&lt;/h2&gt;

&lt;p&gt;Before automating anything, know which kind of PDF you are feeding the pipeline. Select a word in the file. If it highlights, the text is real and conversion is clean and deterministic. If nothing highlights, the page is an image, and you need OCR in the loop, which is still fine but adds a recognition step you should spot-check. Automations break most often because someone assumed every input was a native PDF when half of them were scans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping a converter in a script
&lt;/h2&gt;

&lt;p&gt;The pattern is boring in the best way: watch a folder or a queue, POST each file to a conversion endpoint, write the result somewhere. I use &lt;a href="https://convertica.net/" rel="noopener noreferrer"&gt;Convertica&lt;/a&gt; for the conversion step because it has a free API and does not require an account, so there is no OAuth dance to script around. A single conversion is just a POST with the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://convertica.net/api/v1/pdf-to-word/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@invoice.pdf"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; invoice.docx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop that into a loop and a cron entry and the Monday-invoices chore runs itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail
&lt;span class="nv"&gt;IN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./incoming
&lt;span class="nv"&gt;OUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./converted
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IN&lt;/span&gt;&lt;span class="s2"&gt;/done"&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.pdf&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="p"&gt;%.pdf&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://convertica.net/api/v1/pdf-to-excel/ &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;OUT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.xlsx"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/done/"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# every Monday at 6am
0 6 * * 1 /home/me/scripts/convert-invoices.sh &amp;gt;&amp;gt; /var/log/convert.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;set -euo pipefail&lt;/code&gt; and &lt;code&gt;curl -fsS&lt;/code&gt; matter more than they look. Without them a failed conversion writes a zero-byte file, your &lt;code&gt;mv&lt;/code&gt; marks it done, and you lose the input silently. Fail loudly instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts people skip
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Idempotency.&lt;/strong&gt; Move processed files out of the input folder (or track them) so a re-run does not convert the same file twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scanned inputs.&lt;/strong&gt; If the batch might contain scans, expect OCR and add a sanity check on the output. A zero-length or suspiciously tiny result usually means a bad scan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup.&lt;/strong&gt; Whatever service you use, know its retention. Convertica deletes uploads from the server after a short window, which is what you want for statements and contracts rather than throwaway samples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets stay home.&lt;/strong&gt; For genuinely confidential documents I generate the file from source rather than round-tripping it through any external service, mine included. Automation is for the routine stuff, not the crown jewels.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do not forget the passwords
&lt;/h2&gt;

&lt;p&gt;One thing that quietly breaks batch jobs: a password-protected PDF in the input. There are two kinds, and they fail differently. An owner-password file (restrictions only) usually still converts. An open-password file is encrypted and will not convert without the password, and no tool bypasses real encryption, so your script should catch that case and set the file aside for a human rather than retrying forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;The work has not changed. Files still need to be smaller, converted, and machine-readable. What changed is that the repetitive slice of it belongs in a five-line script and a cron entry. Spend the ten seconds to check text-versus-scan, fail loudly, respect retention, and the Monday chore stops being a chore.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>automation</category>
      <category>api</category>
      <category>productivity</category>
    </item>
    <item>
      <title>PDF Chores You No Longer Need a Desktop App For</title>
      <dc:creator>Convertica</dc:creator>
      <pubDate>Tue, 14 Jul 2026 12:49:03 +0000</pubDate>
      <link>https://dev.to/convertica_01bef32536e9e7/pdf-chores-you-no-longer-need-a-desktop-app-for-602</link>
      <guid>https://dev.to/convertica_01bef32536e9e7/pdf-chores-you-no-longer-need-a-desktop-app-for-602</guid>
      <description>&lt;p&gt;Every few weeks a PDF lands on my desk that needs something done to it. Shrink it so an email will accept it. Pull a table into a spreadsheet. Merge four scans into one file. For years the reflex was to open a heavy desktop app, or worse, to pay for one just to run a two-minute task. That reflex is out of date. Almost all of it now runs in a browser tab, and some of it runs from a script.&lt;/p&gt;

&lt;p&gt;I want to walk through the ones I actually use, and where the line sits between "do it in the browser" and "automate it."&lt;/p&gt;

&lt;h2&gt;
  
  
  The one check that saves you every time
&lt;/h2&gt;

&lt;p&gt;Before touching any PDF tool, find out what kind of file you have. Select a word on the page. If it highlights, the text is real and any conversion will be clean. If nothing highlights, the page is an image (a scan), and you need OCR to get text out of it.&lt;/p&gt;

&lt;p&gt;This sounds trivial, but it explains most "the converter mangled my file" complaints. A native PDF converts faithfully. A scanned one goes through character recognition, which is good but not perfect, so you review the output. Knowing which you have sets your expectations correctly before you start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shrinking a PDF for email
&lt;/h2&gt;

&lt;p&gt;Mail providers still cap attachments low: Gmail at 25 MB, Outlook around 20, plenty of corporate servers at 10. A 300-DPI scan blows past all of them.&lt;/p&gt;

&lt;p&gt;Compression re-encodes the images inside the file while leaving the text sharp. Medium compression is the sweet spot for email: the file drops several times over and you will not see the difference on screen. Keep maximum quality only when the destination is a professional printer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting tables out of a PDF and into a spreadsheet
&lt;/h2&gt;

&lt;p&gt;This is the one that used to eat my afternoons. Copy-pasting a PDF table into a spreadsheet collapses it into a single column of run-together text, because a PDF stores text at fixed coordinates, not as a real grid. A proper conversion reads the position of every value and rebuilds actual cells, so numbers land under the right headers.&lt;/p&gt;

&lt;p&gt;For one-off files, a browser tool is the fastest path. When it becomes routine, say a nightly batch of statements, this is where automation earns its keep.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to reach for an API instead of a tab
&lt;/h2&gt;

&lt;p&gt;The browser is right for occasional work. But if you are converting the same kind of document on a schedule, or building a feature into your own app, you do not want a human clicking upload. That is the point where a free API pays off.&lt;/p&gt;

&lt;p&gt;I have been using &lt;a href="https://convertica.net/" rel="noopener noreferrer"&gt;Convertica&lt;/a&gt; for both sides of this. The web tools cover the ad-hoc jobs (compress, merge, split, PDF to Word or Excel, unlock, and so on) with no signup, and there is an API for wiring conversions into a pipeline. A typical call is nothing more than a POST with the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://convertica.net/api/v1/pdf-to-word/ &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-F&lt;/span&gt; &lt;span class="s2"&gt;"file=@report.pdf"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; report.docx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uploaded files are removed from the server after a short window, which matters when the documents are statements or contracts rather than throwaway samples. For anything genuinely secret, I still generate the file from source rather than round-tripping it through any service, mine or otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note on PDF passwords, since it trips people up
&lt;/h2&gt;

&lt;p&gt;PDFs carry two kinds of password and they behave very differently. An open password encrypts the file: without it, nothing can read the content, and no tool bypasses real encryption in seconds regardless of what its landing page claims. A permissions password only disables copy, print, or edit while letting the file open, and that kind was never strong protection to begin with.&lt;/p&gt;

&lt;p&gt;The practical takeaway for developers: if you need to actually secure a document, set an open password and share it out of band. Do not rely on permission flags, because most readers and libraries ignore them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shift, in one line
&lt;/h2&gt;

&lt;p&gt;The work has not changed. Files still need to be smaller, mergeable, and machine-readable. What changed is that none of it requires a paid desktop install anymore. Occasional jobs go in a browser tab, repeated ones go through an API, and the only real prerequisite is that ten-second check of whether your PDF is text or a picture.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
