跳至页脚内容
视频

IronPDF 2021:Chrome渲染引擎EAP – PDF生成的变革者!

DinkToPdf 封装了 wkhtmltopdf,继承了其所有的安全漏洞和技术限制。 了解这些问题对于评估迁移的紧迫性至关重要。

关键安全问题

DinkToPdf 从 wkhtmltopdf 继承未修补的安全公告:

  1. CVE-2022-35583 (SSRF): 针对 wkhtmltopdf 0.12.6 的一项服务器端请求伪造公告(CVSS 9.8 在 NVD; 被上游项目认为是应用侧输入清理问题而非库缺陷)。 无论怎样,该问题将不会被修补。
  2. 归档项目: wkhtmltopdf/wkhtmltopdf 仓库于2023年1月2日归档,整个 wkhtmltopdf GitHub 组织于2024年7月10日归档。
  3. 无未来安全补丁: 所有已知或未来的漏洞将不上游修复。

技术问题

问题 影响
线程安全 BasicConverter 仅支持单线程; SynchronizedConverter 序列化调用,并且在负载下可能仍然导致本地端崩溃
本地二进制文件 复杂部署与平台特定的 libwkhtmltox 二进制文件
CSS限制 旧的 QtWebKit 叉——不支持现代Flexbox/Grid布局
JavaScript语言 执行不一致、超时
渲染 过时的基于 QtWebKit 的引擎(wkhtmltopdf 0.12.6,最后发布于 2020 年 6 月)
维护 DinkToPdf 1.0.8 最后版本发布于 2017年4月18日 在 NuGet

架构比较

方面 DinkToPdf IronPDF
安全性 CVE-2022-35583 (SSRF),未修补 / 上游有争议 没有已知的关键CVE
渲染引擎 旧的 QtWebKit 分支 (wkhtmltopdf 0.12.6) 现代 Chromium
线程安全 SynchronizedConverter 序列化调用; native-side crashes reported under load 线程安全设计
本地依赖关系 平台特定的 libwkhtmltox 二进制文件 已管理的NuGet包
CSS支持 没有现代Flexbox/Grid 完整的 CSS3
JavaScript语言 有限、不一致 支持
维护 DinkToPdf 最后版本发布于 2017年4月 wkhtmltopdf 组织于 2024年7月 归档 积极维护

功能对比

特征 DinkToPdf IronPDF
HTML 至 PDF ✅(过时的引擎) ✅(Chromium)
URL 至 PDF
自定义页边距
页眉/页脚 ✅(有限) ✅ (完整 HTML)
CSS3 ❌ 有限公司 ✅ 全文
Flexbox/Grid
JavaScript ⚠ 限制 ✅ 全文
PDF 操作
表格填写
数字签名
加密
水印
合并/拆分

迁移前准备

前提条件

确保您的环境符合这些要求:

  • .NET Framework 4.6.2+, .NET Core 3.1+, or .NET 5/6/7/8/9/10
  • Visual Studio 2019+ 或带有 C# 扩展的 VS Code
  • 访问 NuGet 包管理器 -IronPDF许可证密钥(可在ironpdf.com免费试用)

审核DinkToPdf的使用情况

在您的解决方案目录中运行这些命令,以识别所有DinkToPdf引用:

# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .

# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .

# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .

# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .

# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
SHELL

值得期待的重大变化

变更 DinkToPdf IronPDF 影响
转换器 SynchronizedConverter(new PdfTools()) ChromePdfRenderer 更简单的实例化
文档 HtmlToPdfDocument 直接方法调用 无文档对象
设置 GlobalSettings + ObjectSettings RenderingOptions 单一选项对象
返回类型 byte[] PdfDocument 更强大的对象
二进制 libwkhtmltox.dll/so 无(托管) 删除本地文件
线程安全 BasicConverter 单线程; SynchronizedConverter 序列化 默认为线程安全 简化代码
DI 需要单例 终生 灵活

逐步迁移过程

步骤 1:更新 NuGet 软件包

移除DinkToPdf并安装 IronPDF:

# Remove DinkToPdf
dotnet remove package DinkToPdf

# Install IronPDF
dotnet add package IronPdf
# Remove DinkToPdf
dotnet remove package DinkToPdf

# Install IronPDF
dotnet add package IronPdf
SHELL

步骤 2:删除本地二进制文件

从您的项目中删除这些特定于平台的文件:

  • libwkhtmltox.dll (Windows)
  • libwkhtmltox.so (Linux)
  • libwkhtmltox.dylib (macOS)

IronPDF 没有本地依赖性--一切都是托管代码。

步骤 3:更新命名空间引用

用IronPDF替换DinkToPdf命名空间:

// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;

// Add this
using IronPdf;
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;

// Add this
using IronPdf;
Imports IronPdf
$vbLabelText   $csharpLabel

步骤 4:配置许可证

// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

完整的 API 迁移参考

核心类映射

DinkToPdf IronPDF
SynchronizedConverter ChromePdfRenderer
BasicConverter ChromePdfRenderer
PdfTools 不需要
HtmlToPdfDocument 不需要
GlobalSettings RenderingOptions
ObjectSettings RenderingOptions
MarginSettings 个别边距属性

全局设置映射

DinkToPdf 全局设置 IronPDF 同等产品
ColorMode = ColorMode.Color 默认(始终为彩色)
Orientation = Orientation.Portrait PaperOrientation = PdfPaperOrientation.Portrait
Orientation = Orientation.Landscape PaperOrientation = PdfPaperOrientation.Landscape
PaperSize = PaperKind.A4 PaperSize = PdfPaperSize.A4
Margins = new MarginSettings() 个别边距属性

边距设置映射

DinkToPdf 边界 IronPDF 同等产品
Margins.Top = 10 MarginTop = 10
Margins.Bottom = 10 MarginBottom = 10
Margins.Left = 15 MarginLeft = 15
Margins.Right = 15 MarginRight = 15

代码迁移示例

将基本 HTML 转换为 PDF.

基本转换演示了从DinkToPdf的冗长配置到IronPDF的精简 API 的巨大简化。

DinkToPdf实现:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    .WebSettings = New WebSettings() With {
                        .DefaultEncoding = "utf-8"
                    }
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF 可将 20 行的DinkToPdf配置缩减为 4 行。 没有 SynchronizedConverter,没有 PdfTools,没有 HtmlToPdfDocument,没有 ObjectSettings——只需渲染并保存。 有关更多选项,请参阅 HTML 转 PDF 文档

URL到PDF转换

DinkToPdf实现:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = New List(Of ObjectSettings) From {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF 的 RenderUrlAsPdf 用直接的方法调用替换了嵌套的 ObjectSettings.Page 配置。 有关更多选项,请参阅 URL to PDF 文档

横向和页边距自定义设置

DinkToPdf实现:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom.pdf", pdf);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {
                    .Top = 10,
                    .Bottom = 10,
                    .Left = 15,
                    .Right = 15
                }
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    .WebSettings = New WebSettings() With {
                        .DefaultEncoding = "utf-8"
                    }
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 实现:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 15;
        renderer.RenderingOptions.MarginRight = 15;

        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 15;
        renderer.RenderingOptions.MarginRight = 15;

        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
        pdf.SaveAs("custom.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Module Program
    Sub Main()
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 15
        renderer.RenderingOptions.MarginRight = 15

        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>")
        pdf.SaveAs("custom.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 的 RenderingOptions 用统一的、流畅的 API 替代了 GlobalSettingsMarginSettings。 有关更多配置选项,请参阅渲染选项文档

关键迁移说明

删除本地二进制文件

最重要的清理步骤是删除 wkhtmltopdf 本机二进制文件。IronPDF没有本地依赖性:

# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
SHELL

无需单例

DinkToPdf 的文档指导是将 SynchronizedConverter 注册为单例。IronPDF的 ChromePdfRenderer 在任何 DI 生命周期内都是线程安全的:

//DinkToPdf- typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
//DinkToPdf- typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
' DinkToPdf - typically registered as singleton
services.AddSingleton(GetType(IConverter), New SynchronizedConverter(New PdfTools()))

' IronPDF - any lifetime works
services.AddScoped(Of ChromePdfRenderer)()
' Or just create inline:
Dim renderer As New ChromePdfRenderer()
$vbLabelText   $csharpLabel

Richer 返回类型

DinkToPdf 返回 byte[]。IronPDF返回具有操作能力的 PdfDocument

//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");

//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");

//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
' DinkToPdf returns byte()
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
Return File(pdf, "application/pdf")

' IronPDF returns PdfDocument
Dim pdfDocument = renderer.RenderHtmlAsPdf(html)
pdfDocument.SaveAs("output.pdf")
Return File(pdfDocument.BinaryData, "application/pdf")
$vbLabelText   $csharpLabel

完全支持 CSS3.

在DinkToPdf中失效的现代布局在IronPDF中可以完美运行:

//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>";  // Broken!

//IronPDF- full support (modern Chromium)
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";
var pdf = renderer.RenderHtmlAsPdf(html);  // Works!
//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>";  // Broken!

//IronPDF- full support (modern Chromium)
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";
var pdf = renderer.RenderHtmlAsPdf(html);  // Works!
' DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
Dim html As String = "<div style='display: flex;'>...</div>"  ' Broken!

' IronPDF- full support (modern Chromium)
Dim html As String = "
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>"
Dim pdf = renderer.RenderHtmlAsPdf(html)  ' Works!
$vbLabelText   $csharpLabel

迁移后核对表

完成代码迁移后,请验证以下内容:

运行所有单元测试以验证 PDF 生成功能是否正常。

  • 测试多线程场景(SynchronizedConverter 路径序列化调用,并且在负载下容易发生本地端崩溃)
  • 对比PDF输出质量(IronPDF的Chromium渲染效果更好)
  • 验证 CSS 渲染效果(Flexbox/Grid 现在正常工作)
  • 测试JavaScript执行(使用IronPDF可确保可靠性)
  • 更新 CI/CD 流水线,移除 wkhtmltopdf 安装
  • 验证安全扫描通过(不再有 CVE-2022-35583 标志)
  • 从 Docker/部署脚本中移除原生二进制部署

其他资源


从DinkToPdf迁移到IronPDF解除了未打补丁的 wkhtmltopdf 攻击面 (CVE-2022-35583)、序列化的 SynchronizedConverter 并发模型、本地二进制部署和较旧的 QtWebKit 渲染路径。 过渡到现代的 Chromium 引擎提供了完整的CSS3支持、可靠的JavaScript执行以及一个被积极维护的库。

请注意DinkToPdf 和 wkhtmltopdf 是其各自所有者的注册商标。 本网站与DinkToPdf或 wkhtmltopdf 无关,并未获得其认可或赞助。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我